| 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 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |