OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
8 #include "src/ast/compile-time-value.h" | 8 #include "src/ast/compile-time-value.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
964 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. | 964 // it to a JS receiver. See ECMA-262 version 5, section 12.6.4. |
965 Label convert, done_convert; | 965 Label convert, done_convert; |
966 __ JumpIfSmi(rax, &convert, Label::kNear); | 966 __ JumpIfSmi(rax, &convert, Label::kNear); |
967 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx); | 967 __ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx); |
968 __ j(above_equal, &done_convert, Label::kNear); | 968 __ j(above_equal, &done_convert, Label::kNear); |
969 __ CompareRoot(rax, Heap::kNullValueRootIndex); | 969 __ CompareRoot(rax, Heap::kNullValueRootIndex); |
970 __ j(equal, &exit); | 970 __ j(equal, &exit); |
971 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); | 971 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
972 __ j(equal, &exit); | 972 __ j(equal, &exit); |
973 __ bind(&convert); | 973 __ bind(&convert); |
974 ToObjectStub stub(isolate()); | 974 __ Call(isolate()->builtins()->ToObject(), RelocInfo::CODE_TARGET); |
975 __ CallStub(&stub); | |
976 RestoreContext(); | 975 RestoreContext(); |
977 __ bind(&done_convert); | 976 __ bind(&done_convert); |
978 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); | 977 PrepareForBailoutForId(stmt->ToObjectId(), BailoutState::TOS_REGISTER); |
979 __ Push(rax); | 978 __ Push(rax); |
980 | 979 |
981 // Check cache validity in generated code. If we cannot guarantee cache | 980 // Check cache validity in generated code. If we cannot guarantee cache |
982 // validity, call the runtime system to check cache validity or get the | 981 // validity, call the runtime system to check cache validity or get the |
983 // property names in a fixed array. Note: Proxies never have an enum cache, | 982 // property names in a fixed array. Note: Proxies never have an enum cache, |
984 // so will always take the slow path. | 983 // so will always take the slow path. |
985 Label call_runtime; | 984 Label call_runtime; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 __ movp(rbx, Operand(rsp, 4 * kPointerSize)); | 1063 __ movp(rbx, Operand(rsp, 4 * kPointerSize)); |
1065 __ cmpp(rdx, FieldOperand(rbx, HeapObject::kMapOffset)); | 1064 __ cmpp(rdx, FieldOperand(rbx, HeapObject::kMapOffset)); |
1066 __ j(equal, &update_each, Label::kNear); | 1065 __ j(equal, &update_each, Label::kNear); |
1067 | 1066 |
1068 // We need to filter the key, record slow-path here. | 1067 // We need to filter the key, record slow-path here. |
1069 int const vector_index = SmiFromSlot(slot)->value(); | 1068 int const vector_index = SmiFromSlot(slot)->value(); |
1070 __ EmitLoadTypeFeedbackVector(rdx); | 1069 __ EmitLoadTypeFeedbackVector(rdx); |
1071 __ Move(FieldOperand(rdx, FixedArray::OffsetOfElementAt(vector_index)), | 1070 __ Move(FieldOperand(rdx, FixedArray::OffsetOfElementAt(vector_index)), |
1072 TypeFeedbackVector::MegamorphicSentinel(isolate())); | 1071 TypeFeedbackVector::MegamorphicSentinel(isolate())); |
1073 | 1072 |
1074 // rax contains the key. The receiver in rbx is the second argument to the | 1073 // rax contains the key. The receiver in rbx is the second argument to |
1075 // ForInFilterStub. ForInFilter returns undefined if the receiver doesn't | 1074 // ForInFilter. ForInFilter returns undefined if the receiver doesn't |
1076 // have the key or returns the name-converted key. | 1075 // have the key or returns the name-converted key. |
1077 ForInFilterStub has_stub(isolate()); | 1076 __ Call(isolate()->builtins()->ForInFilter(), RelocInfo::CODE_TARGET); |
1078 __ CallStub(&has_stub); | |
1079 RestoreContext(); | 1077 RestoreContext(); |
1080 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); | 1078 PrepareForBailoutForId(stmt->FilterId(), BailoutState::TOS_REGISTER); |
1081 __ JumpIfRoot(result_register(), Heap::kUndefinedValueRootIndex, | 1079 __ JumpIfRoot(result_register(), Heap::kUndefinedValueRootIndex, |
1082 loop_statement.continue_label()); | 1080 loop_statement.continue_label()); |
1083 | 1081 |
1084 // Update the 'each' property or variable from the possibly filtered | 1082 // Update the 'each' property or variable from the possibly filtered |
1085 // entry in register rax. | 1083 // entry in register rax. |
1086 __ bind(&update_each); | 1084 __ bind(&update_each); |
1087 // Perform the assignment as if via '='. | 1085 // Perform the assignment as if via '='. |
1088 { EffectContext context(this); | 1086 { EffectContext context(this); |
(...skipping 1841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2930 break; | 2928 break; |
2931 } | 2929 } |
2932 | 2930 |
2933 case Token::TYPEOF: { | 2931 case Token::TYPEOF: { |
2934 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); | 2932 Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)"); |
2935 { | 2933 { |
2936 AccumulatorValueContext context(this); | 2934 AccumulatorValueContext context(this); |
2937 VisitForTypeofValue(expr->expression()); | 2935 VisitForTypeofValue(expr->expression()); |
2938 } | 2936 } |
2939 __ movp(rbx, rax); | 2937 __ movp(rbx, rax); |
2940 TypeofStub typeof_stub(isolate()); | 2938 __ Call(isolate()->builtins()->Typeof(), RelocInfo::CODE_TARGET); |
2941 __ CallStub(&typeof_stub); | |
2942 context()->Plug(rax); | 2939 context()->Plug(rax); |
2943 break; | 2940 break; |
2944 } | 2941 } |
2945 | 2942 |
2946 default: | 2943 default: |
2947 UNREACHABLE(); | 2944 UNREACHABLE(); |
2948 } | 2945 } |
2949 } | 2946 } |
2950 | 2947 |
2951 | 2948 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3299 EmitHasProperty(); | 3296 EmitHasProperty(); |
3300 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3297 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3301 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 3298 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
3302 Split(equal, if_true, if_false, fall_through); | 3299 Split(equal, if_true, if_false, fall_through); |
3303 break; | 3300 break; |
3304 | 3301 |
3305 case Token::INSTANCEOF: { | 3302 case Token::INSTANCEOF: { |
3306 VisitForAccumulatorValue(expr->right()); | 3303 VisitForAccumulatorValue(expr->right()); |
3307 SetExpressionPosition(expr); | 3304 SetExpressionPosition(expr); |
3308 PopOperand(rdx); | 3305 PopOperand(rdx); |
3309 InstanceOfStub stub(isolate()); | 3306 __ Call(isolate()->builtins()->InstanceOf(), RelocInfo::CODE_TARGET); |
3310 __ CallStub(&stub); | |
3311 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); | 3307 PrepareForBailoutBeforeSplit(expr, false, NULL, NULL); |
3312 __ CompareRoot(rax, Heap::kTrueValueRootIndex); | 3308 __ CompareRoot(rax, Heap::kTrueValueRootIndex); |
3313 Split(equal, if_true, if_false, fall_through); | 3309 Split(equal, if_true, if_false, fall_through); |
3314 break; | 3310 break; |
3315 } | 3311 } |
3316 | 3312 |
3317 default: { | 3313 default: { |
3318 VisitForAccumulatorValue(expr->right()); | 3314 VisitForAccumulatorValue(expr->right()); |
3319 SetExpressionPosition(expr); | 3315 SetExpressionPosition(expr); |
3320 Condition cc = CompareIC::ComputeCondition(op); | 3316 Condition cc = CompareIC::ComputeCondition(op); |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3554 DCHECK_EQ( | 3550 DCHECK_EQ( |
3555 isolate->builtins()->OnStackReplacement()->entry(), | 3551 isolate->builtins()->OnStackReplacement()->entry(), |
3556 Assembler::target_address_at(call_target_address, unoptimized_code)); | 3552 Assembler::target_address_at(call_target_address, unoptimized_code)); |
3557 return ON_STACK_REPLACEMENT; | 3553 return ON_STACK_REPLACEMENT; |
3558 } | 3554 } |
3559 | 3555 |
3560 } // namespace internal | 3556 } // namespace internal |
3561 } // namespace v8 | 3557 } // namespace v8 |
3562 | 3558 |
3563 #endif // V8_TARGET_ARCH_X64 | 3559 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |