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