Chromium Code Reviews| 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 |