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

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

Issue 1128193005: [turbofan] Use FrameStatesBeforeAndAfter to simplify handling of before/after frame states in AstGr… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/js-type-feedback.h" 10 #include "src/compiler/js-type-feedback.h"
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 control_->LeaveTry(token, value); 377 control_->LeaveTry(token, value);
378 return true; 378 return true;
379 } 379 }
380 380
381 private: 381 private:
382 DeferredCommands* commands_; 382 DeferredCommands* commands_;
383 TryFinallyBuilder* control_; 383 TryFinallyBuilder* control_;
384 }; 384 };
385 385
386 386
387 // Helper for generating before and after frame states.
388 class AstGraphBuilder::FrameStateBeforeAndAfter {
389 public:
390 FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before)
391 : builder_(builder), frame_state_before_(nullptr) {
392 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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698