Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1128193005: [turbofan] Use FrameStatesBeforeAndAfter to simplify handling of before/after frame states in AstGr… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/js-type-feedback.h" 10 #include "src/compiler/js-type-feedback.h"
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 control_->LeaveTry(token, value); 377 control_->LeaveTry(token, value);
378 return true; 378 return true;
379 } 379 }
380 380
381 private: 381 private:
382 DeferredCommands* commands_; 382 DeferredCommands* commands_;
383 TryFinallyBuilder* control_; 383 TryFinallyBuilder* control_;
384 }; 384 };
385 385
386 386
387 // Helper for generating before and after frame states.
388 class AstGraphBuilder::FrameStateBeforeAndAfter {
389 public:
390 FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before)
391 : builder_(builder), frame_state_before_(nullptr) {
392 frame_state_before_ = id_before == BailoutId::None()
393 ? builder_->jsgraph()->EmptyFrameState()
394 : builder_->environment()->Checkpoint(id_before);
395 }
396
397 void AddToNode(Node* node, BailoutId id_after,
398 OutputFrameStateCombine combine) {
399 int count = OperatorProperties::GetFrameStateInputCount(node->op());
400 DCHECK_LE(count, 2);
401
402 if (count >= 1) {
403 // Add the frame state for after the operation.
404 DCHECK_EQ(IrOpcode::kDead,
405 NodeProperties::GetFrameStateInput(node, 0)->opcode());
406
407 Node* frame_state_after =
408 id_after == BailoutId::None()
409 ? builder_->jsgraph()->EmptyFrameState()
410 : builder_->environment()->Checkpoint(id_after, combine);
411
412 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
413 }
414
415 if (count >= 2) {
416 // Add the frame state for before the operation.
417 DCHECK_EQ(IrOpcode::kDead,
418 NodeProperties::GetFrameStateInput(node, 1)->opcode());
419 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
420 }
421 }
422
423 private:
424 AstGraphBuilder* builder_;
425 Node* frame_state_before_;
426 };
427
428
387 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info, 429 AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
388 JSGraph* jsgraph, LoopAssignmentAnalysis* loop, 430 JSGraph* jsgraph, LoopAssignmentAnalysis* loop,
389 JSTypeFeedbackTable* js_type_feedback) 431 JSTypeFeedbackTable* js_type_feedback)
390 : local_zone_(local_zone), 432 : local_zone_(local_zone),
391 info_(info), 433 info_(info),
392 jsgraph_(jsgraph), 434 jsgraph_(jsgraph),
393 environment_(nullptr), 435 environment_(nullptr),
394 ast_context_(nullptr), 436 ast_context_(nullptr),
395 globals_(0, local_zone), 437 globals_(0, local_zone),
396 execution_control_(nullptr), 438 execution_control_(nullptr),
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode()), 1339 javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, language_mode()),
1298 function, obj, value); 1340 function, obj, value);
1299 PrepareFrameState(res, stmt->FilterId(), OutputFrameStateCombine::Push()); 1341 PrepareFrameState(res, stmt->FilterId(), OutputFrameStateCombine::Push());
1300 Node* property_missing = 1342 Node* property_missing =
1301 NewNode(javascript()->StrictEqual(), res, jsgraph()->ZeroConstant()); 1343 NewNode(javascript()->StrictEqual(), res, jsgraph()->ZeroConstant());
1302 { 1344 {
1303 IfBuilder is_property_missing(this); 1345 IfBuilder is_property_missing(this);
1304 is_property_missing.If(property_missing); 1346 is_property_missing.If(property_missing);
1305 is_property_missing.Then(); 1347 is_property_missing.Then();
1306 // Inc counter and continue. 1348 // Inc counter and continue.
1307 Node* index_inc = 1349 {
1308 NewNode(javascript()->Add(LanguageMode::SLOPPY), index, 1350 // TODO(jarin): provide real bailout id.
1309 jsgraph()->OneConstant()); 1351 FrameStateBeforeAndAfter states(this, BailoutId::None());
1310 // TODO(jarin): provide real bailout id. 1352 Node* index_inc = NewNode(javascript()->Add(LanguageMode::SLOPPY),
1311 PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(), 1353 index, jsgraph()->OneConstant());
1312 OutputFrameStateCombine::Ignore(), 1354 states.AddToNode(index_inc, BailoutId::None(),
1313 jsgraph()->EmptyFrameState()); 1355 OutputFrameStateCombine::Ignore());
1314 environment()->Poke(0, index_inc); 1356 environment()->Poke(0, index_inc);
1357 }
1315 for_loop.Continue(); 1358 for_loop.Continue();
1316 is_property_missing.Else(); 1359 is_property_missing.Else();
1317 is_property_missing.End(); 1360 is_property_missing.End();
1318 } 1361 }
1319 // Replace 'value' in environment. 1362 // Replace 'value' in environment.
1320 environment()->Push(res); 1363 environment()->Push(res);
1321 test_should_filter.Else(); 1364 test_should_filter.Else();
1322 test_should_filter.End(); 1365 test_should_filter.End();
1323 } 1366 }
1324 value = environment()->Pop(); 1367 value = environment()->Pop();
1325 // Bind value and do loop body. 1368 // Bind value and do loop body.
1326 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); 1369 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId());
1327 VisitIterationBody(stmt, &for_loop); 1370 VisitIterationBody(stmt, &for_loop);
1328 index = environment()->Peek(0); 1371 index = environment()->Peek(0);
1329 for_loop.EndBody(); 1372 for_loop.EndBody();
1330 1373
1331 // Inc counter and continue. 1374 // Inc counter and continue.
1332 Node* index_inc = 1375 Node* index_inc =
1333 NewNode(javascript()->Add(LanguageMode::SLOPPY), index, 1376 NewNode(javascript()->Add(LanguageMode::SLOPPY), index,
1334 jsgraph()->OneConstant()); 1377 jsgraph()->OneConstant());
1335 // TODO(jarin): provide real bailout id. 1378 {
1336 PrepareFrameStateAfterAndBefore(index_inc, BailoutId::None(), 1379 // TODO(jarin): provide real bailout ids.
1337 OutputFrameStateCombine::Ignore(), 1380 FrameStateBeforeAndAfter states(this, BailoutId::None());
1338 jsgraph()->EmptyFrameState()); 1381 states.AddToNode(index_inc, BailoutId::None(),
1382 OutputFrameStateCombine::Ignore());
1383 }
1339 environment()->Poke(0, index_inc); 1384 environment()->Poke(0, index_inc);
1340 for_loop.EndLoop(); 1385 for_loop.EndLoop();
1341 environment()->Drop(5); 1386 environment()->Drop(5);
1342 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); 1387 // PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
1343 } 1388 }
1344 1389
1345 1390
1346 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 1391 void AstGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
1347 LoopBuilder for_loop(this); 1392 LoopBuilder for_loop(this);
1348 VisitForEffect(stmt->assign_iterator()); 1393 VisitForEffect(stmt->assign_iterator());
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 environment()->Push(literal); 1908 environment()->Push(literal);
1864 environment()->Push(literal_index); 1909 environment()->Push(literal_index);
1865 1910
1866 // Create nodes to evaluate all the non-constant subexpressions and to store 1911 // Create nodes to evaluate all the non-constant subexpressions and to store
1867 // them into the newly cloned array. 1912 // them into the newly cloned array.
1868 for (int i = 0; i < expr->values()->length(); i++) { 1913 for (int i = 0; i < expr->values()->length(); i++) {
1869 Expression* subexpr = expr->values()->at(i); 1914 Expression* subexpr = expr->values()->at(i);
1870 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 1915 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
1871 1916
1872 VisitForValue(subexpr); 1917 VisitForValue(subexpr);
1873 Node* frame_state_before = environment()->Checkpoint( 1918 {
1874 subexpr->id(), OutputFrameStateCombine::PokeAt(0)); 1919 FrameStateBeforeAndAfter states(this, subexpr->id());
1875 Node* value = environment()->Pop(); 1920 Node* value = environment()->Pop();
1876 Node* index = jsgraph()->Constant(i); 1921 Node* index = jsgraph()->Constant(i);
1877 Node* store = 1922 Node* store =
1878 BuildKeyedStore(literal, index, value, TypeFeedbackId::None()); 1923 BuildKeyedStore(literal, index, value, TypeFeedbackId::None());
1879 PrepareFrameStateAfterAndBefore(store, expr->GetIdForElement(i), 1924 states.AddToNode(store, expr->GetIdForElement(i),
1880 OutputFrameStateCombine::Ignore(), 1925 OutputFrameStateCombine::Ignore());
1881 frame_state_before); 1926 }
1882 } 1927 }
1883 1928
1884 environment()->Pop(); // Array literal index. 1929 environment()->Pop(); // Array literal index.
1885 ast_context()->ProduceValue(environment()->Pop()); 1930 ast_context()->ProduceValue(environment()->Pop());
1886 } 1931 }
1887 1932
1888 1933
1889 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, 1934 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value,
1890 BailoutId bailout_id) { 1935 BailoutId bailout_id) {
1891 DCHECK(expr->IsValidReferenceExpression()); 1936 DCHECK(expr->IsValidReferenceExpression());
(...skipping 17 matching lines...) Expand all
1909 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 1954 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
1910 Node* store = 1955 Node* store =
1911 BuildNamedStore(object, name, value, TypeFeedbackId::None()); 1956 BuildNamedStore(object, name, value, TypeFeedbackId::None());
1912 PrepareFrameState(store, bailout_id); 1957 PrepareFrameState(store, bailout_id);
1913 break; 1958 break;
1914 } 1959 }
1915 case KEYED_PROPERTY: { 1960 case KEYED_PROPERTY: {
1916 environment()->Push(value); 1961 environment()->Push(value);
1917 VisitForValue(property->obj()); 1962 VisitForValue(property->obj());
1918 VisitForValue(property->key()); 1963 VisitForValue(property->key());
1919 Node* key = environment()->Pop(); 1964 {
1920 Node* object = environment()->Pop(); 1965 // TODO(jarin) Provide a real frame state before.
1921 value = environment()->Pop(); 1966 FrameStateBeforeAndAfter states(this, BailoutId::None());
1922 Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None()); 1967 Node* key = environment()->Pop();
1923 // TODO(jarin) Provide a real frame state before. 1968 Node* object = environment()->Pop();
1924 PrepareFrameStateAfterAndBefore(store, bailout_id, 1969 value = environment()->Pop();
1925 OutputFrameStateCombine::Ignore(), 1970 Node* store =
1926 jsgraph()->EmptyFrameState()); 1971 BuildKeyedStore(object, key, value, TypeFeedbackId::None());
1972 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore());
1973 }
1927 break; 1974 break;
1928 } 1975 }
1929 } 1976 }
1930 } 1977 }
1931 1978
1932 1979
1933 void AstGraphBuilder::VisitAssignment(Assignment* expr) { 1980 void AstGraphBuilder::VisitAssignment(Assignment* expr) {
1934 DCHECK(expr->target()->IsValidReferenceExpression()); 1981 DCHECK(expr->target()->IsValidReferenceExpression());
1935 1982
1936 // Left-hand side can only be a property, a global or a variable slot. 1983 // Left-hand side can only be a property, a global or a variable slot.
1937 Property* property = expr->target()->AsProperty(); 1984 Property* property = expr->target()->AsProperty();
1938 LhsKind assign_type = DetermineLhsKind(expr->target()); 1985 LhsKind assign_type = DetermineLhsKind(expr->target());
1986 bool needs_frame_state_before = true;
1939 1987
1940 // Evaluate LHS expression. 1988 // Evaluate LHS expression.
1941 switch (assign_type) { 1989 switch (assign_type) {
1942 case VARIABLE: 1990 case VARIABLE: {
1943 // Nothing to do here. 1991 Variable* variable = expr->target()->AsVariableProxy()->var();
1992 if (variable->location() == Variable::PARAMETER ||
1993 variable->location() == Variable::LOCAL ||
1994 variable->location() == Variable::CONTEXT) {
1995 needs_frame_state_before = false;
1996 }
1944 break; 1997 break;
1998 }
1945 case NAMED_PROPERTY: 1999 case NAMED_PROPERTY:
1946 VisitForValue(property->obj()); 2000 VisitForValue(property->obj());
1947 break; 2001 break;
1948 case KEYED_PROPERTY: { 2002 case KEYED_PROPERTY: {
1949 VisitForValue(property->obj()); 2003 VisitForValue(property->obj());
1950 VisitForValue(property->key()); 2004 VisitForValue(property->key());
1951 break; 2005 break;
1952 } 2006 }
1953 } 2007 }
1954 2008
2009 BailoutId before_store_id = BailoutId::None();
1955 // Evaluate the value and potentially handle compound assignments by loading 2010 // Evaluate the value and potentially handle compound assignments by loading
1956 // the left-hand side value and performing a binary operation. 2011 // the left-hand side value and performing a binary operation.
1957 Node* frame_state_before_store = nullptr;
1958 bool needs_frame_state_before = (assign_type == KEYED_PROPERTY);
1959 if (expr->is_compound()) { 2012 if (expr->is_compound()) {
1960 Node* old_value = NULL; 2013 Node* old_value = NULL;
1961 switch (assign_type) { 2014 switch (assign_type) {
1962 case VARIABLE: { 2015 case VARIABLE: {
1963 VariableProxy* proxy = expr->target()->AsVariableProxy(); 2016 VariableProxy* proxy = expr->target()->AsVariableProxy();
1964 VectorSlotPair pair = 2017 VectorSlotPair pair =
1965 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); 2018 CreateVectorSlotPair(proxy->VariableFeedbackSlot());
1966 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair); 2019 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair);
1967 break; 2020 break;
1968 } 2021 }
(...skipping 15 matching lines...) Expand all
1984 CreateVectorSlotPair(property->PropertyFeedbackSlot()); 2037 CreateVectorSlotPair(property->PropertyFeedbackSlot());
1985 old_value = 2038 old_value =
1986 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId()); 2039 BuildKeyedLoad(object, key, pair, property->PropertyFeedbackId());
1987 PrepareFrameState(old_value, property->LoadId(), 2040 PrepareFrameState(old_value, property->LoadId(),
1988 OutputFrameStateCombine::Push()); 2041 OutputFrameStateCombine::Push());
1989 break; 2042 break;
1990 } 2043 }
1991 } 2044 }
1992 environment()->Push(old_value); 2045 environment()->Push(old_value);
1993 VisitForValue(expr->value()); 2046 VisitForValue(expr->value());
1994 Node* frame_state_before = environment()->Checkpoint(expr->value()->id()); 2047 Node* value;
1995 Node* right = environment()->Pop(); 2048 {
1996 Node* left = environment()->Pop(); 2049 FrameStateBeforeAndAfter states(this, expr->value()->id());
1997 Node* value = BuildBinaryOp(left, right, expr->binary_op()); 2050 Node* right = environment()->Pop();
1998 PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(), 2051 Node* left = environment()->Pop();
1999 OutputFrameStateCombine::Push(), 2052 value = BuildBinaryOp(left, right, expr->binary_op());
2000 frame_state_before); 2053 states.AddToNode(value, expr->binary_operation()->id(),
2054 OutputFrameStateCombine::Push());
2055 }
2001 environment()->Push(value); 2056 environment()->Push(value);
2002 if (needs_frame_state_before) { 2057 if (needs_frame_state_before) {
2003 frame_state_before_store = environment()->Checkpoint( 2058 before_store_id = expr->binary_operation()->id();
2004 expr->binary_operation()->id(), OutputFrameStateCombine::PokeAt(0));
2005 } 2059 }
2006 } else { 2060 } else {
2007 VisitForValue(expr->value()); 2061 VisitForValue(expr->value());
2008 if (needs_frame_state_before) { 2062 if (needs_frame_state_before) {
2009 // This frame state can be used for lazy-deopting from a to-number 2063 before_store_id = expr->value()->id();
2010 // conversion if we are storing into a typed array. It is important
2011 // that the frame state is usable for such lazy deopt (i.e., it has
2012 // to specify how to override the value before the conversion, in this
2013 // case, it overwrites the stack top).
2014 frame_state_before_store = environment()->Checkpoint(
2015 expr->value()->id(), OutputFrameStateCombine::PokeAt(0));
2016 } 2064 }
2017 } 2065 }
2018 2066
2067 FrameStateBeforeAndAfter store_states(this, before_store_id);
2019 // Store the value. 2068 // Store the value.
2020 Node* value = environment()->Pop(); 2069 Node* value = environment()->Pop();
2021 switch (assign_type) { 2070 switch (assign_type) {
2022 case VARIABLE: { 2071 case VARIABLE: {
2023 Variable* variable = expr->target()->AsVariableProxy()->var(); 2072 Variable* variable = expr->target()->AsVariableProxy()->var();
2024 BuildVariableAssignment(variable, value, expr->op(), expr->id(), 2073 BuildVariableAssignment(variable, value, expr->op(), expr->id(),
2025 ast_context()->GetStateCombine()); 2074 ast_context()->GetStateCombine());
2026 break; 2075 break;
2027 } 2076 }
2028 case NAMED_PROPERTY: { 2077 case NAMED_PROPERTY: {
2029 Node* object = environment()->Pop(); 2078 Node* object = environment()->Pop();
2030 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 2079 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2031 Node* store = 2080 Node* store =
2032 BuildNamedStore(object, name, value, expr->AssignmentFeedbackId()); 2081 BuildNamedStore(object, name, value, expr->AssignmentFeedbackId());
2033 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); 2082 store_states.AddToNode(store, expr->id(),
2083 ast_context()->GetStateCombine());
2034 break; 2084 break;
2035 } 2085 }
2036 case KEYED_PROPERTY: { 2086 case KEYED_PROPERTY: {
2037 Node* key = environment()->Pop(); 2087 Node* key = environment()->Pop();
2038 Node* object = environment()->Pop(); 2088 Node* object = environment()->Pop();
2039 Node* store = 2089 Node* store =
2040 BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId()); 2090 BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId());
2041 PrepareFrameStateAfterAndBefore(store, expr->id(), 2091 store_states.AddToNode(store, expr->id(),
2042 ast_context()->GetStateCombine(), 2092 ast_context()->GetStateCombine());
2043 frame_state_before_store);
2044 break; 2093 break;
2045 } 2094 }
2046 } 2095 }
2047 2096
2048 ast_context()->ProduceValue(value); 2097 ast_context()->ProduceValue(value);
2049 } 2098 }
2050 2099
2051 2100
2052 void AstGraphBuilder::VisitYield(Yield* expr) { 2101 void AstGraphBuilder::VisitYield(Yield* expr) {
2053 // TODO(turbofan): Implement yield here. 2102 // TODO(turbofan): Implement yield here.
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 stack_depth = 2; 2404 stack_depth = 2;
2356 break; 2405 break;
2357 } 2406 }
2358 } 2407 }
2359 2408
2360 // Convert old value into a number. 2409 // Convert old value into a number.
2361 old_value = NewNode(javascript()->ToNumber(), old_value); 2410 old_value = NewNode(javascript()->ToNumber(), old_value);
2362 PrepareFrameState(old_value, expr->ToNumberId(), 2411 PrepareFrameState(old_value, expr->ToNumberId(),
2363 OutputFrameStateCombine::Push()); 2412 OutputFrameStateCombine::Push());
2364 2413
2365 Node* frame_state_before_store = 2414 // TODO(titzer): combine this framestate with the above?
2366 assign_type == KEYED_PROPERTY 2415 FrameStateBeforeAndAfter store_states(this, assign_type == KEYED_PROPERTY
2367 ? environment()->Checkpoint(expr->ToNumberId()) 2416 ? expr->ToNumberId()
2368 : nullptr; 2417 : BailoutId::None());
2369 2418
2370 // Save result for postfix expressions at correct stack depth. 2419 // Save result for postfix expressions at correct stack depth.
2371 if (is_postfix) environment()->Poke(stack_depth, old_value); 2420 if (is_postfix) environment()->Poke(stack_depth, old_value);
2372 2421
2373 // Create node to perform +1/-1 operation. 2422 // Create node to perform +1/-1 operation.
2374 Node* value = 2423 Node* value;
2375 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); 2424 {
2376 // This should never deoptimize because we have converted to number 2425 FrameStateBeforeAndAfter states(this, BailoutId::None());
2377 // before. 2426 value =
2378 PrepareFrameStateAfterAndBefore(value, BailoutId::None(), 2427 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op());
2379 OutputFrameStateCombine::Ignore(), 2428 // This should never deoptimize because we have converted to number
2380 jsgraph()->EmptyFrameState()); 2429 // before.
2430 states.AddToNode(value, BailoutId::None(),
2431 OutputFrameStateCombine::Ignore());
2432 }
2381 2433
2382 // Store the value. 2434 // Store the value.
2383 switch (assign_type) { 2435 switch (assign_type) {
2384 case VARIABLE: { 2436 case VARIABLE: {
2385 Variable* variable = expr->expression()->AsVariableProxy()->var(); 2437 Variable* variable = expr->expression()->AsVariableProxy()->var();
2386 environment()->Push(value); 2438 environment()->Push(value);
2387 BuildVariableAssignment(variable, value, expr->op(), 2439 BuildVariableAssignment(variable, value, expr->op(),
2388 expr->AssignmentId()); 2440 expr->AssignmentId());
2389 environment()->Pop(); 2441 environment()->Pop();
2390 break; 2442 break;
2391 } 2443 }
2392 case NAMED_PROPERTY: { 2444 case NAMED_PROPERTY: {
2393 Node* object = environment()->Pop(); 2445 Node* object = environment()->Pop();
2394 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 2446 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2395 Node* store = 2447 Node* store =
2396 BuildNamedStore(object, name, value, expr->CountStoreFeedbackId()); 2448 BuildNamedStore(object, name, value, expr->CountStoreFeedbackId());
2397 environment()->Push(value); 2449 environment()->Push(value);
2398 PrepareFrameState(store, expr->AssignmentId()); 2450 PrepareFrameState(store, expr->AssignmentId());
2399 environment()->Pop(); 2451 environment()->Pop();
2400 break; 2452 break;
2401 } 2453 }
2402 case KEYED_PROPERTY: { 2454 case KEYED_PROPERTY: {
2403 Node* key = environment()->Pop(); 2455 Node* key = environment()->Pop();
2404 Node* object = environment()->Pop(); 2456 Node* object = environment()->Pop();
2405 Node* store = 2457 Node* store =
2406 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId()); 2458 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId());
2407 environment()->Push(value); 2459 environment()->Push(value);
2408 PrepareFrameStateAfterAndBefore(store, expr->AssignmentId(), 2460 store_states.AddToNode(store, expr->AssignmentId(),
2409 OutputFrameStateCombine::Ignore(), 2461 OutputFrameStateCombine::Ignore());
2410 frame_state_before_store);
2411 environment()->Pop(); 2462 environment()->Pop();
2412 break; 2463 break;
2413 } 2464 }
2414 } 2465 }
2415 2466
2416 // Restore old value for postfix expressions. 2467 // Restore old value for postfix expressions.
2417 if (is_postfix) value = environment()->Pop(); 2468 if (is_postfix) value = environment()->Pop();
2418 2469
2419 ast_context()->ProduceValue(value); 2470 ast_context()->ProduceValue(value);
2420 } 2471 }
2421 2472
2422 2473
2423 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 2474 void AstGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
2424 switch (expr->op()) { 2475 switch (expr->op()) {
2425 case Token::COMMA: 2476 case Token::COMMA:
2426 return VisitComma(expr); 2477 return VisitComma(expr);
2427 case Token::OR: 2478 case Token::OR:
2428 case Token::AND: 2479 case Token::AND:
2429 return VisitLogicalExpression(expr); 2480 return VisitLogicalExpression(expr);
2430 default: { 2481 default: {
2431 VisitForValue(expr->left()); 2482 VisitForValue(expr->left());
2432 VisitForValue(expr->right()); 2483 VisitForValue(expr->right());
2433 Node* frame_state_before = environment()->Checkpoint(expr->right()->id()); 2484 FrameStateBeforeAndAfter states(this, expr->right()->id());
2434 Node* right = environment()->Pop(); 2485 Node* right = environment()->Pop();
2435 Node* left = environment()->Pop(); 2486 Node* left = environment()->Pop();
2436 Node* value = BuildBinaryOp(left, right, expr->op()); 2487 Node* value = BuildBinaryOp(left, right, expr->op());
2437 PrepareFrameStateAfterAndBefore(value, expr->id(), 2488 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine());
2438 ast_context()->GetStateCombine(),
2439 frame_state_before);
2440 ast_context()->ProduceValue(value); 2489 ast_context()->ProduceValue(value);
2441 } 2490 }
2442 } 2491 }
2443 } 2492 }
2444 2493
2445 2494
2446 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 2495 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
2447 const Operator* op; 2496 const Operator* op;
2448 switch (expr->op()) { 2497 switch (expr->op()) {
2449 case Token::EQ: 2498 case Token::EQ:
(...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after
3290 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 3339 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
3291 3340
3292 DCHECK_EQ(IrOpcode::kDead, 3341 DCHECK_EQ(IrOpcode::kDead,
3293 NodeProperties::GetFrameStateInput(node, 0)->opcode()); 3342 NodeProperties::GetFrameStateInput(node, 0)->opcode());
3294 NodeProperties::ReplaceFrameStateInput( 3343 NodeProperties::ReplaceFrameStateInput(
3295 node, 0, environment()->Checkpoint(ast_id, combine)); 3344 node, 0, environment()->Checkpoint(ast_id, combine));
3296 } 3345 }
3297 } 3346 }
3298 3347
3299 3348
3300 void AstGraphBuilder::PrepareFrameStateAfterAndBefore(
3301 Node* node, BailoutId ast_id, OutputFrameStateCombine combine,
3302 Node* frame_state_before) {
3303 if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) {
3304 DCHECK_EQ(2, OperatorProperties::GetFrameStateInputCount(node->op()));
3305
3306 DCHECK_EQ(IrOpcode::kDead,
3307 NodeProperties::GetFrameStateInput(node, 0)->opcode());
3308 NodeProperties::ReplaceFrameStateInput(
3309 node, 0, environment()->Checkpoint(ast_id, combine));
3310
3311 DCHECK_EQ(IrOpcode::kDead,
3312 NodeProperties::GetFrameStateInput(node, 1)->opcode());
3313 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before);
3314 }
3315 }
3316
3317
3318 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( 3349 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
3319 IterationStatement* stmt) { 3350 IterationStatement* stmt) {
3320 if (loop_assignment_analysis_ == NULL) return NULL; 3351 if (loop_assignment_analysis_ == NULL) return NULL;
3321 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); 3352 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
3322 } 3353 }
3323 3354
3324 3355
3325 Node** AstGraphBuilder::EnsureInputBufferSize(int size) { 3356 Node** AstGraphBuilder::EnsureInputBufferSize(int size) {
3326 if (size > input_buffer_size_) { 3357 if (size > input_buffer_size_) {
3327 size = size + kInputBufferSizeIncrement + input_buffer_size_; 3358 size = size + kInputBufferSizeIncrement + input_buffer_size_;
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
3605 // Phi does not exist yet, introduce one. 3636 // Phi does not exist yet, introduce one.
3606 value = NewPhi(inputs, value, control); 3637 value = NewPhi(inputs, value, control);
3607 value->ReplaceInput(inputs - 1, other); 3638 value->ReplaceInput(inputs - 1, other);
3608 } 3639 }
3609 return value; 3640 return value;
3610 } 3641 }
3611 3642
3612 } // namespace compiler 3643 } // namespace compiler
3613 } // namespace internal 3644 } // namespace internal
3614 } // namespace v8 3645 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698