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/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
9 #include "src/compiler/ast-loop-assignment-analyzer.h" | 9 #include "src/compiler/ast-loop-assignment-analyzer.h" |
10 #include "src/compiler/control-builders.h" | 10 #include "src/compiler/control-builders.h" |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 275 |
276 protected: | 276 protected: |
277 Node* NewPathToken(int token_id) { | 277 Node* NewPathToken(int token_id) { |
278 return owner_->jsgraph()->Constant(token_id); | 278 return owner_->jsgraph()->Constant(token_id); |
279 } | 279 } |
280 Node* NewPathTokenForImplicitFallThrough() { | 280 Node* NewPathTokenForImplicitFallThrough() { |
281 return NewPathToken(TokenDispenserForFinally::kFallThroughToken); | 281 return NewPathToken(TokenDispenserForFinally::kFallThroughToken); |
282 } | 282 } |
283 Node* NewPathDispatchCondition(Node* t1, Node* t2) { | 283 Node* NewPathDispatchCondition(Node* t1, Node* t2) { |
284 return owner_->NewNode( | 284 return owner_->NewNode( |
285 owner_->javascript()->StrictEqual(CompareOperationHints::Any()), t1, | 285 owner_->javascript()->StrictEqual(CompareOperationHint::kAny), t1, t2); |
286 t2); | |
287 } | 286 } |
288 | 287 |
289 private: | 288 private: |
290 TokenDispenserForFinally dispenser_; | 289 TokenDispenserForFinally dispenser_; |
291 AstGraphBuilder* owner_; | 290 AstGraphBuilder* owner_; |
292 ZoneVector<Entry> deferred_; | 291 ZoneVector<Entry> deferred_; |
293 Node* return_token_; | 292 Node* return_token_; |
294 Node* throw_token_; | 293 Node* throw_token_; |
295 }; | 294 }; |
296 | 295 |
(...skipping 970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 default_index = i; | 1266 default_index = i; |
1268 continue; | 1267 continue; |
1269 } | 1268 } |
1270 | 1269 |
1271 // Create nodes to perform label comparison as if via '==='. The switch | 1270 // Create nodes to perform label comparison as if via '==='. The switch |
1272 // value is still on the operand stack while the label is evaluated. | 1271 // value is still on the operand stack while the label is evaluated. |
1273 VisitForValue(clause->label()); | 1272 VisitForValue(clause->label()); |
1274 Node* label = environment()->Pop(); | 1273 Node* label = environment()->Pop(); |
1275 Node* tag = environment()->Top(); | 1274 Node* tag = environment()->Top(); |
1276 | 1275 |
1277 CompareOperationHints hints; | 1276 CompareOperationHint hint; |
1278 if (!type_hint_analysis_ || | 1277 if (!type_hint_analysis_ || |
1279 !type_hint_analysis_->GetCompareOperationHints(clause->CompareId(), | 1278 !type_hint_analysis_->GetCompareOperationHint(clause->CompareId(), |
1280 &hints)) { | 1279 &hint)) { |
1281 hints = CompareOperationHints::Any(); | 1280 hint = CompareOperationHint::kAny; |
1282 } | 1281 } |
1283 | 1282 |
1284 const Operator* op = javascript()->StrictEqual(hints); | 1283 const Operator* op = javascript()->StrictEqual(hint); |
1285 Node* condition = NewNode(op, tag, label); | 1284 Node* condition = NewNode(op, tag, label); |
1286 compare_switch.BeginLabel(i, condition); | 1285 compare_switch.BeginLabel(i, condition); |
1287 | 1286 |
1288 // Discard the switch value at label match. | 1287 // Discard the switch value at label match. |
1289 environment()->Pop(); | 1288 environment()->Pop(); |
1290 compare_switch.EndLabel(); | 1289 compare_switch.EndLabel(); |
1291 } | 1290 } |
1292 | 1291 |
1293 // Discard the switch value and mark the default case. | 1292 // Discard the switch value and mark the default case. |
1294 environment()->Pop(); | 1293 environment()->Pop(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 } | 1349 } |
1351 | 1350 |
1352 | 1351 |
1353 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { | 1352 void AstGraphBuilder::VisitForInStatement(ForInStatement* stmt) { |
1354 VisitForValue(stmt->subject()); | 1353 VisitForValue(stmt->subject()); |
1355 Node* object = environment()->Pop(); | 1354 Node* object = environment()->Pop(); |
1356 BlockBuilder for_block(this); | 1355 BlockBuilder for_block(this); |
1357 for_block.BeginBlock(); | 1356 for_block.BeginBlock(); |
1358 // Check for null or undefined before entering loop. | 1357 // Check for null or undefined before entering loop. |
1359 Node* is_null_cond = | 1358 Node* is_null_cond = |
1360 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object, | 1359 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object, |
1361 jsgraph()->NullConstant()); | 1360 jsgraph()->NullConstant()); |
1362 for_block.BreakWhen(is_null_cond, BranchHint::kFalse); | 1361 for_block.BreakWhen(is_null_cond, BranchHint::kFalse); |
1363 Node* is_undefined_cond = | 1362 Node* is_undefined_cond = |
1364 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), object, | 1363 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), object, |
1365 jsgraph()->UndefinedConstant()); | 1364 jsgraph()->UndefinedConstant()); |
1366 for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse); | 1365 for_block.BreakWhen(is_undefined_cond, BranchHint::kFalse); |
1367 { | 1366 { |
1368 // Convert object to jsobject. | 1367 // Convert object to jsobject. |
1369 object = BuildToObject(object, stmt->ToObjectId()); | 1368 object = BuildToObject(object, stmt->ToObjectId()); |
1370 environment()->Push(object); | 1369 environment()->Push(object); |
1371 | 1370 |
1372 // Prepare for-in cache. | 1371 // Prepare for-in cache. |
1373 Node* prepare = NewNode(javascript()->ForInPrepare(), object); | 1372 Node* prepare = NewNode(javascript()->ForInPrepare(), object); |
1374 PrepareFrameState(prepare, stmt->PrepareId(), | 1373 PrepareFrameState(prepare, stmt->PrepareId(), |
(...skipping 24 matching lines...) Expand all Loading... |
1399 Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length); | 1398 Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length); |
1400 for_loop.BreakWhen(exit_cond); | 1399 for_loop.BreakWhen(exit_cond); |
1401 | 1400 |
1402 // Compute the next enumerated value. | 1401 // Compute the next enumerated value. |
1403 Node* value = NewNode(javascript()->ForInNext(), object, cache_array, | 1402 Node* value = NewNode(javascript()->ForInNext(), object, cache_array, |
1404 cache_type, index); | 1403 cache_type, index); |
1405 PrepareFrameState(value, stmt->FilterId(), | 1404 PrepareFrameState(value, stmt->FilterId(), |
1406 OutputFrameStateCombine::Push()); | 1405 OutputFrameStateCombine::Push()); |
1407 IfBuilder test_value(this); | 1406 IfBuilder test_value(this); |
1408 Node* test_value_cond = | 1407 Node* test_value_cond = |
1409 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 1408 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), value, |
1410 value, jsgraph()->UndefinedConstant()); | 1409 jsgraph()->UndefinedConstant()); |
1411 test_value.If(test_value_cond, BranchHint::kFalse); | 1410 test_value.If(test_value_cond, BranchHint::kFalse); |
1412 test_value.Then(); | 1411 test_value.Then(); |
1413 test_value.Else(); | 1412 test_value.Else(); |
1414 { | 1413 { |
1415 environment()->Push(value); | 1414 environment()->Push(value); |
1416 PrepareEagerCheckpoint(stmt->FilterId()); | 1415 PrepareEagerCheckpoint(stmt->FilterId()); |
1417 value = environment()->Pop(); | 1416 value = environment()->Pop(); |
1418 // Bind value and do loop body. | 1417 // Bind value and do loop body. |
1419 VectorSlotPair feedback = | 1418 VectorSlotPair feedback = |
1420 CreateVectorSlotPair(stmt->EachFeedbackSlot()); | 1419 CreateVectorSlotPair(stmt->EachFeedbackSlot()); |
(...skipping 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2749 } | 2748 } |
2750 } | 2749 } |
2751 } | 2750 } |
2752 | 2751 |
2753 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, | 2752 void AstGraphBuilder::VisitLiteralCompareNil(CompareOperation* expr, |
2754 Expression* sub_expr, | 2753 Expression* sub_expr, |
2755 Node* nil_value) { | 2754 Node* nil_value) { |
2756 const Operator* op = nullptr; | 2755 const Operator* op = nullptr; |
2757 switch (expr->op()) { | 2756 switch (expr->op()) { |
2758 case Token::EQ: | 2757 case Token::EQ: |
2759 op = javascript()->Equal(CompareOperationHints::Any()); | 2758 op = javascript()->Equal(CompareOperationHint::kAny); |
2760 break; | 2759 break; |
2761 case Token::EQ_STRICT: | 2760 case Token::EQ_STRICT: |
2762 op = javascript()->StrictEqual(CompareOperationHints::Any()); | 2761 op = javascript()->StrictEqual(CompareOperationHint::kAny); |
2763 break; | 2762 break; |
2764 default: | 2763 default: |
2765 UNREACHABLE(); | 2764 UNREACHABLE(); |
2766 } | 2765 } |
2767 VisitForValue(sub_expr); | 2766 VisitForValue(sub_expr); |
2768 Node* value_to_compare = environment()->Pop(); | 2767 Node* value_to_compare = environment()->Pop(); |
2769 Node* value = NewNode(op, value_to_compare, nil_value); | 2768 Node* value = NewNode(op, value_to_compare, nil_value); |
2770 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2769 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2771 return ast_context()->ProduceValue(expr, value); | 2770 return ast_context()->ProduceValue(expr, value); |
2772 } | 2771 } |
2773 | 2772 |
2774 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, | 2773 void AstGraphBuilder::VisitLiteralCompareTypeof(CompareOperation* expr, |
2775 Expression* sub_expr, | 2774 Expression* sub_expr, |
2776 Handle<String> check) { | 2775 Handle<String> check) { |
2777 VisitTypeofExpression(sub_expr); | 2776 VisitTypeofExpression(sub_expr); |
2778 Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); | 2777 Node* typeof_arg = NewNode(javascript()->TypeOf(), environment()->Pop()); |
2779 Node* value = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 2778 Node* value = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
2780 typeof_arg, jsgraph()->Constant(check)); | 2779 typeof_arg, jsgraph()->Constant(check)); |
2781 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2780 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2782 return ast_context()->ProduceValue(expr, value); | 2781 return ast_context()->ProduceValue(expr, value); |
2783 } | 2782 } |
2784 | 2783 |
2785 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 2784 void AstGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
2786 // Check for a few fast cases. The AST visiting behavior must be in sync | 2785 // Check for a few fast cases. The AST visiting behavior must be in sync |
2787 // with the full codegen: We don't push both left and right values onto | 2786 // with the full codegen: We don't push both left and right values onto |
2788 // the expression stack when one side is a special-case literal. | 2787 // the expression stack when one side is a special-case literal. |
2789 Expression* sub_expr = nullptr; | 2788 Expression* sub_expr = nullptr; |
2790 Handle<String> check; | 2789 Handle<String> check; |
2791 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { | 2790 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { |
2792 return VisitLiteralCompareTypeof(expr, sub_expr, check); | 2791 return VisitLiteralCompareTypeof(expr, sub_expr, check); |
2793 } | 2792 } |
2794 if (expr->IsLiteralCompareUndefined(&sub_expr)) { | 2793 if (expr->IsLiteralCompareUndefined(&sub_expr)) { |
2795 return VisitLiteralCompareNil(expr, sub_expr, | 2794 return VisitLiteralCompareNil(expr, sub_expr, |
2796 jsgraph()->UndefinedConstant()); | 2795 jsgraph()->UndefinedConstant()); |
2797 } | 2796 } |
2798 if (expr->IsLiteralCompareNull(&sub_expr)) { | 2797 if (expr->IsLiteralCompareNull(&sub_expr)) { |
2799 return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant()); | 2798 return VisitLiteralCompareNil(expr, sub_expr, jsgraph()->NullConstant()); |
2800 } | 2799 } |
2801 | 2800 |
2802 CompareOperationHints hints; | 2801 CompareOperationHint hint; |
2803 if (!type_hint_analysis_ || | 2802 if (!type_hint_analysis_ || |
2804 !type_hint_analysis_->GetCompareOperationHints( | 2803 !type_hint_analysis_->GetCompareOperationHint( |
2805 expr->CompareOperationFeedbackId(), &hints)) { | 2804 expr->CompareOperationFeedbackId(), &hint)) { |
2806 hints = CompareOperationHints::Any(); | 2805 hint = CompareOperationHint::kAny; |
2807 } | 2806 } |
2808 | 2807 |
2809 const Operator* op; | 2808 const Operator* op; |
2810 switch (expr->op()) { | 2809 switch (expr->op()) { |
2811 case Token::EQ: | 2810 case Token::EQ: |
2812 op = javascript()->Equal(hints); | 2811 op = javascript()->Equal(hint); |
2813 break; | 2812 break; |
2814 case Token::NE: | 2813 case Token::NE: |
2815 op = javascript()->NotEqual(hints); | 2814 op = javascript()->NotEqual(hint); |
2816 break; | 2815 break; |
2817 case Token::EQ_STRICT: | 2816 case Token::EQ_STRICT: |
2818 op = javascript()->StrictEqual(hints); | 2817 op = javascript()->StrictEqual(hint); |
2819 break; | 2818 break; |
2820 case Token::NE_STRICT: | 2819 case Token::NE_STRICT: |
2821 op = javascript()->StrictNotEqual(hints); | 2820 op = javascript()->StrictNotEqual(hint); |
2822 break; | 2821 break; |
2823 case Token::LT: | 2822 case Token::LT: |
2824 op = javascript()->LessThan(hints); | 2823 op = javascript()->LessThan(hint); |
2825 break; | 2824 break; |
2826 case Token::GT: | 2825 case Token::GT: |
2827 op = javascript()->GreaterThan(hints); | 2826 op = javascript()->GreaterThan(hint); |
2828 break; | 2827 break; |
2829 case Token::LTE: | 2828 case Token::LTE: |
2830 op = javascript()->LessThanOrEqual(hints); | 2829 op = javascript()->LessThanOrEqual(hint); |
2831 break; | 2830 break; |
2832 case Token::GTE: | 2831 case Token::GTE: |
2833 op = javascript()->GreaterThanOrEqual(hints); | 2832 op = javascript()->GreaterThanOrEqual(hint); |
2834 break; | 2833 break; |
2835 case Token::INSTANCEOF: | 2834 case Token::INSTANCEOF: |
2836 op = javascript()->InstanceOf(); | 2835 op = javascript()->InstanceOf(); |
2837 break; | 2836 break; |
2838 case Token::IN: | 2837 case Token::IN: |
2839 op = javascript()->HasProperty(); | 2838 op = javascript()->HasProperty(); |
2840 break; | 2839 break; |
2841 default: | 2840 default: |
2842 op = nullptr; | 2841 op = nullptr; |
2843 UNREACHABLE(); | 2842 UNREACHABLE(); |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3265 BailoutId::None()); | 3264 BailoutId::None()); |
3266 return object; | 3265 return object; |
3267 } | 3266 } |
3268 | 3267 |
3269 | 3268 |
3270 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, | 3269 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, |
3271 Node* not_hole, | 3270 Node* not_hole, |
3272 BailoutId bailout_id) { | 3271 BailoutId bailout_id) { |
3273 IfBuilder hole_check(this); | 3272 IfBuilder hole_check(this); |
3274 Node* the_hole = jsgraph()->TheHoleConstant(); | 3273 Node* the_hole = jsgraph()->TheHoleConstant(); |
3275 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 3274 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
3276 value, the_hole); | 3275 value, the_hole); |
3277 hole_check.If(check); | 3276 hole_check.If(check); |
3278 hole_check.Then(); | 3277 hole_check.Then(); |
3279 Node* error = BuildThrowReferenceError(variable, bailout_id); | 3278 Node* error = BuildThrowReferenceError(variable, bailout_id); |
3280 environment()->Push(error); | 3279 environment()->Push(error); |
3281 hole_check.Else(); | 3280 hole_check.Else(); |
3282 environment()->Push(not_hole); | 3281 environment()->Push(not_hole); |
3283 hole_check.End(); | 3282 hole_check.End(); |
3284 return environment()->Pop(); | 3283 return environment()->Pop(); |
3285 } | 3284 } |
3286 | 3285 |
3287 | 3286 |
3288 Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable, | 3287 Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable, |
3289 Node* for_hole, | 3288 Node* for_hole, |
3290 BailoutId bailout_id) { | 3289 BailoutId bailout_id) { |
3291 IfBuilder hole_check(this); | 3290 IfBuilder hole_check(this); |
3292 Node* the_hole = jsgraph()->TheHoleConstant(); | 3291 Node* the_hole = jsgraph()->TheHoleConstant(); |
3293 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 3292 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
3294 value, the_hole); | 3293 value, the_hole); |
3295 hole_check.If(check); | 3294 hole_check.If(check); |
3296 hole_check.Then(); | 3295 hole_check.Then(); |
3297 environment()->Push(for_hole); | 3296 environment()->Push(for_hole); |
3298 hole_check.Else(); | 3297 hole_check.Else(); |
3299 Node* error = BuildThrowReferenceError(variable, bailout_id); | 3298 Node* error = BuildThrowReferenceError(variable, bailout_id); |
3300 environment()->Push(error); | 3299 environment()->Push(error); |
3301 hole_check.End(); | 3300 hole_check.End(); |
3302 return environment()->Pop(); | 3301 return environment()->Pop(); |
3303 } | 3302 } |
3304 | 3303 |
3305 | 3304 |
3306 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name, | 3305 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name, |
3307 BailoutId bailout_id) { | 3306 BailoutId bailout_id) { |
3308 IfBuilder prototype_check(this); | 3307 IfBuilder prototype_check(this); |
3309 Node* prototype_string = | 3308 Node* prototype_string = |
3310 jsgraph()->Constant(isolate()->factory()->prototype_string()); | 3309 jsgraph()->Constant(isolate()->factory()->prototype_string()); |
3311 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), | 3310 Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
3312 name, prototype_string); | 3311 name, prototype_string); |
3313 prototype_check.If(check); | 3312 prototype_check.If(check); |
3314 prototype_check.Then(); | 3313 prototype_check.Then(); |
3315 Node* error = BuildThrowStaticPrototypeError(bailout_id); | 3314 Node* error = BuildThrowStaticPrototypeError(bailout_id); |
3316 environment()->Push(error); | 3315 environment()->Push(error); |
3317 prototype_check.Else(); | 3316 prototype_check.Else(); |
3318 environment()->Push(name); | 3317 environment()->Push(name); |
3319 prototype_check.End(); | 3318 prototype_check.End(); |
3320 return environment()->Pop(); | 3319 return environment()->Pop(); |
3321 } | 3320 } |
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3771 NewNode(javascript()->CallRuntime(Runtime::kReThrow), exception_value); | 3770 NewNode(javascript()->CallRuntime(Runtime::kReThrow), exception_value); |
3772 Node* control = NewNode(common()->Throw(), exception_value); | 3771 Node* control = NewNode(common()->Throw(), exception_value); |
3773 UpdateControlDependencyToLeaveFunction(control); | 3772 UpdateControlDependencyToLeaveFunction(control); |
3774 return control; | 3773 return control; |
3775 } | 3774 } |
3776 | 3775 |
3777 | 3776 |
3778 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op, | 3777 Node* AstGraphBuilder::BuildBinaryOp(Node* left, Node* right, Token::Value op, |
3779 TypeFeedbackId feedback_id) { | 3778 TypeFeedbackId feedback_id) { |
3780 const Operator* js_op; | 3779 const Operator* js_op; |
3781 BinaryOperationHints hints; | 3780 BinaryOperationHint hint; |
3782 if (!type_hint_analysis_ || | 3781 if (!type_hint_analysis_ || |
3783 !type_hint_analysis_->GetBinaryOperationHints(feedback_id, &hints)) { | 3782 !type_hint_analysis_->GetBinaryOperationHint(feedback_id, &hint)) { |
3784 hints = BinaryOperationHints::Any(); | 3783 hint = BinaryOperationHint::kAny; |
3785 } | 3784 } |
3786 switch (op) { | 3785 switch (op) { |
3787 case Token::BIT_OR: | 3786 case Token::BIT_OR: |
3788 js_op = javascript()->BitwiseOr(hints); | 3787 js_op = javascript()->BitwiseOr(hint); |
3789 break; | 3788 break; |
3790 case Token::BIT_AND: | 3789 case Token::BIT_AND: |
3791 js_op = javascript()->BitwiseAnd(hints); | 3790 js_op = javascript()->BitwiseAnd(hint); |
3792 break; | 3791 break; |
3793 case Token::BIT_XOR: | 3792 case Token::BIT_XOR: |
3794 js_op = javascript()->BitwiseXor(hints); | 3793 js_op = javascript()->BitwiseXor(hint); |
3795 break; | 3794 break; |
3796 case Token::SHL: | 3795 case Token::SHL: |
3797 js_op = javascript()->ShiftLeft(hints); | 3796 js_op = javascript()->ShiftLeft(hint); |
3798 break; | 3797 break; |
3799 case Token::SAR: | 3798 case Token::SAR: |
3800 js_op = javascript()->ShiftRight(hints); | 3799 js_op = javascript()->ShiftRight(hint); |
3801 break; | 3800 break; |
3802 case Token::SHR: | 3801 case Token::SHR: |
3803 js_op = javascript()->ShiftRightLogical(hints); | 3802 js_op = javascript()->ShiftRightLogical(hint); |
3804 break; | 3803 break; |
3805 case Token::ADD: | 3804 case Token::ADD: |
3806 js_op = javascript()->Add(hints); | 3805 js_op = javascript()->Add(hint); |
3807 break; | 3806 break; |
3808 case Token::SUB: | 3807 case Token::SUB: |
3809 js_op = javascript()->Subtract(hints); | 3808 js_op = javascript()->Subtract(hint); |
3810 break; | 3809 break; |
3811 case Token::MUL: | 3810 case Token::MUL: |
3812 js_op = javascript()->Multiply(hints); | 3811 js_op = javascript()->Multiply(hint); |
3813 break; | 3812 break; |
3814 case Token::DIV: | 3813 case Token::DIV: |
3815 js_op = javascript()->Divide(hints); | 3814 js_op = javascript()->Divide(hint); |
3816 break; | 3815 break; |
3817 case Token::MOD: | 3816 case Token::MOD: |
3818 js_op = javascript()->Modulus(hints); | 3817 js_op = javascript()->Modulus(hint); |
3819 break; | 3818 break; |
3820 default: | 3819 default: |
3821 UNREACHABLE(); | 3820 UNREACHABLE(); |
3822 js_op = nullptr; | 3821 js_op = nullptr; |
3823 } | 3822 } |
3824 return NewNode(js_op, left, right); | 3823 return NewNode(js_op, left, right); |
3825 } | 3824 } |
3826 | 3825 |
3827 | 3826 |
3828 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { | 3827 Node* AstGraphBuilder::TryLoadGlobalConstant(Handle<Name> name) { |
(...skipping 24 matching lines...) Expand all Loading... |
3853 fast_block.BeginBlock(); | 3852 fast_block.BeginBlock(); |
3854 | 3853 |
3855 // Perform checks whether the fast mode applies, by looking for any | 3854 // Perform checks whether the fast mode applies, by looking for any |
3856 // extension object which might shadow the optimistic declaration. | 3855 // extension object which might shadow the optimistic declaration. |
3857 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) { | 3856 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) { |
3858 if ((bitset & 1) == 0) continue; | 3857 if ((bitset & 1) == 0) continue; |
3859 Node* load = NewNode( | 3858 Node* load = NewNode( |
3860 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 3859 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), |
3861 current_context()); | 3860 current_context()); |
3862 Node* check = | 3861 Node* check = |
3863 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load, | 3862 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load, |
3864 jsgraph()->TheHoleConstant()); | 3863 jsgraph()->TheHoleConstant()); |
3865 fast_block.BreakUnless(check, BranchHint::kTrue); | 3864 fast_block.BreakUnless(check, BranchHint::kTrue); |
3866 } | 3865 } |
3867 | 3866 |
3868 // Fast case, because variable is not shadowed. | 3867 // Fast case, because variable is not shadowed. |
3869 if (Node* constant = TryLoadGlobalConstant(name)) { | 3868 if (Node* constant = TryLoadGlobalConstant(name)) { |
3870 environment()->Push(constant); | 3869 environment()->Push(constant); |
3871 } else { | 3870 } else { |
3872 // Perform global slot load. | 3871 // Perform global slot load. |
3873 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode); | 3872 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode); |
(...skipping 26 matching lines...) Expand all Loading... |
3900 fast_block.BeginBlock(); | 3899 fast_block.BeginBlock(); |
3901 | 3900 |
3902 // Perform checks whether the fast mode applies, by looking for any | 3901 // Perform checks whether the fast mode applies, by looking for any |
3903 // extension object which might shadow the optimistic declaration. | 3902 // extension object which might shadow the optimistic declaration. |
3904 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) { | 3903 for (int depth = 0; bitset != 0; bitset >>= 1, depth++) { |
3905 if ((bitset & 1) == 0) continue; | 3904 if ((bitset & 1) == 0) continue; |
3906 Node* load = NewNode( | 3905 Node* load = NewNode( |
3907 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), | 3906 javascript()->LoadContext(depth, Context::EXTENSION_INDEX, false), |
3908 current_context()); | 3907 current_context()); |
3909 Node* check = | 3908 Node* check = |
3910 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()), load, | 3909 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), load, |
3911 jsgraph()->TheHoleConstant()); | 3910 jsgraph()->TheHoleConstant()); |
3912 fast_block.BreakUnless(check, BranchHint::kTrue); | 3911 fast_block.BreakUnless(check, BranchHint::kTrue); |
3913 } | 3912 } |
3914 | 3913 |
3915 // Fast case, because variable is not shadowed. Perform context slot load. | 3914 // Fast case, because variable is not shadowed. Perform context slot load. |
3916 Variable* local = variable->local_if_not_shadowed(); | 3915 Variable* local = variable->local_if_not_shadowed(); |
3917 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context. | 3916 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context. |
3918 Node* fast = | 3917 Node* fast = |
3919 BuildVariableLoad(local, bailout_id, feedback, combine, typeof_mode); | 3918 BuildVariableLoad(local, bailout_id, feedback, combine, typeof_mode); |
3920 environment()->Push(fast); | 3919 environment()->Push(fast); |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4321 // Phi does not exist yet, introduce one. | 4320 // Phi does not exist yet, introduce one. |
4322 value = NewPhi(inputs, value, control); | 4321 value = NewPhi(inputs, value, control); |
4323 value->ReplaceInput(inputs - 1, other); | 4322 value->ReplaceInput(inputs - 1, other); |
4324 } | 4323 } |
4325 return value; | 4324 return value; |
4326 } | 4325 } |
4327 | 4326 |
4328 } // namespace compiler | 4327 } // namespace compiler |
4329 } // namespace internal | 4328 } // namespace internal |
4330 } // namespace v8 | 4329 } // namespace v8 |
OLD | NEW |