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 |