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

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 157543002: A64: Synchronize with r18581. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 if (info()->IsOptimizing()) { 168 if (info()->IsOptimizing()) {
169 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 169 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
170 170
171 #ifdef DEBUG 171 #ifdef DEBUG
172 if (strlen(FLAG_stop_at) > 0 && 172 if (strlen(FLAG_stop_at) > 0 &&
173 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 173 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
174 __ int3(); 174 __ int3();
175 } 175 }
176 #endif 176 #endif
177 177
178 // Strict mode functions and builtins need to replace the receiver 178 // Classic mode functions and builtins need to replace the receiver with the
179 // with undefined when called as functions (without an explicit 179 // global proxy when called as functions (without an explicit receiver
180 // receiver object). ecx is zero for method calls and non-zero for 180 // object).
181 // function calls. 181 if (info_->this_has_uses() &&
182 if (!info_->is_classic_mode() || info_->is_native()) { 182 info_->is_classic_mode() &&
183 !info_->is_native()) {
183 Label ok; 184 Label ok;
184 __ test(ecx, Operand(ecx)); 185 __ test(ecx, ecx);
185 __ j(zero, &ok, Label::kNear); 186 __ j(zero, &ok, Label::kNear);
187
186 // +1 for return address. 188 // +1 for return address.
187 int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize; 189 int receiver_offset = (scope()->num_parameters() + 1) * kPointerSize;
188 __ mov(Operand(esp, receiver_offset), 190 __ mov(ecx, Operand(esp, receiver_offset));
189 Immediate(isolate()->factory()->undefined_value())); 191
192 __ cmp(ecx, isolate()->factory()->undefined_value());
193 __ j(not_equal, &ok, Label::kNear);
194
195 __ mov(ecx, GlobalObjectOperand());
196 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
197
198 __ mov(Operand(esp, receiver_offset), ecx);
199
190 __ bind(&ok); 200 __ bind(&ok);
191 } 201 }
192 202
193 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) { 203 if (support_aligned_spilled_doubles_ && dynamic_frame_alignment_) {
194 // Move state of dynamic frame alignment into edx. 204 // Move state of dynamic frame alignment into edx.
195 __ Set(edx, Immediate(kNoAlignmentPadding)); 205 __ Set(edx, Immediate(kNoAlignmentPadding));
196 206
197 Label do_not_pad, align_loop; 207 Label do_not_pad, align_loop;
198 STATIC_ASSERT(kDoubleSize == 2 * kPointerSize); 208 STATIC_ASSERT(kDoubleSize == 2 * kPointerSize);
199 // Align esp + 4 to a multiple of 2 * kPointerSize. 209 // Align esp + 4 to a multiple of 2 * kPointerSize.
(...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 ASSERT(ToRegister(instr->left()).is(eax)); 1618 ASSERT(ToRegister(instr->left()).is(eax));
1609 ASSERT(ToRegister(instr->result()).is(edx)); 1619 ASSERT(ToRegister(instr->result()).is(edx));
1610 Register scratch = ToRegister(instr->temp()); 1620 Register scratch = ToRegister(instr->temp());
1611 1621
1612 // Find b which: 2^b < divisor_abs < 2^(b+1). 1622 // Find b which: 2^b < divisor_abs < 2^(b+1).
1613 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); 1623 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs);
1614 unsigned shift = 32 + b; // Precision +1bit (effectively). 1624 unsigned shift = 32 + b; // Precision +1bit (effectively).
1615 double multiplier_f = 1625 double multiplier_f =
1616 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; 1626 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs;
1617 int64_t multiplier; 1627 int64_t multiplier;
1618 if (multiplier_f - floor(multiplier_f) < 0.5) { 1628 if (multiplier_f - std::floor(multiplier_f) < 0.5) {
1619 multiplier = static_cast<int64_t>(floor(multiplier_f)); 1629 multiplier = static_cast<int64_t>(std::floor(multiplier_f));
1620 } else { 1630 } else {
1621 multiplier = static_cast<int64_t>(floor(multiplier_f)) + 1; 1631 multiplier = static_cast<int64_t>(std::floor(multiplier_f)) + 1;
1622 } 1632 }
1623 // The multiplier is a uint32. 1633 // The multiplier is a uint32.
1624 ASSERT(multiplier > 0 && 1634 ASSERT(multiplier > 0 &&
1625 multiplier < (static_cast<int64_t>(1) << 32)); 1635 multiplier < (static_cast<int64_t>(1) << 32));
1626 __ mov(scratch, dividend); 1636 __ mov(scratch, dividend);
1627 if (divisor < 0 && 1637 if (divisor < 0 &&
1628 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 1638 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
1629 __ test(dividend, dividend); 1639 __ test(dividend, dividend);
1630 DeoptimizeIf(zero, instr->environment()); 1640 DeoptimizeIf(zero, instr->environment());
1631 } 1641 }
(...skipping 1525 matching lines...) Expand 10 before | Expand all | Expand 10 after
3157 } 3167 }
3158 } 3168 }
3159 3169
3160 3170
3161 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { 3171 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
3162 ASSERT(ToRegister(instr->context()).is(esi)); 3172 ASSERT(ToRegister(instr->context()).is(esi));
3163 ASSERT(ToRegister(instr->global_object()).is(edx)); 3173 ASSERT(ToRegister(instr->global_object()).is(edx));
3164 ASSERT(ToRegister(instr->result()).is(eax)); 3174 ASSERT(ToRegister(instr->result()).is(eax));
3165 3175
3166 __ mov(ecx, instr->name()); 3176 __ mov(ecx, instr->name());
3167 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : 3177 ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
3168 RelocInfo::CODE_TARGET_CONTEXT; 3178 Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
3169 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3179 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3170 CallCode(ic, mode, instr);
3171 } 3180 }
3172 3181
3173 3182
3174 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { 3183 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
3175 Register value = ToRegister(instr->value()); 3184 Register value = ToRegister(instr->value());
3176 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle(); 3185 Handle<PropertyCell> cell_handle = instr->hydrogen()->cell().handle();
3177 3186
3178 // If the cell we are storing to contains the hole it could have 3187 // If the cell we are storing to contains the hole it could have
3179 // been deleted from the property dictionary. In that case, we need 3188 // been deleted from the property dictionary. In that case, we need
3180 // to update the property details in the property dictionary to mark 3189 // to update the property details in the property dictionary to mark
3181 // it as no longer deleted. We deoptimize in that case. 3190 // it as no longer deleted. We deoptimize in that case.
3182 if (instr->hydrogen()->RequiresHoleCheck()) { 3191 if (instr->hydrogen()->RequiresHoleCheck()) {
3183 __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value()); 3192 __ cmp(Operand::ForCell(cell_handle), factory()->the_hole_value());
3184 DeoptimizeIf(equal, instr->environment()); 3193 DeoptimizeIf(equal, instr->environment());
3185 } 3194 }
3186 3195
3187 // Store the value. 3196 // Store the value.
3188 __ mov(Operand::ForCell(cell_handle), value); 3197 __ mov(Operand::ForCell(cell_handle), value);
3189 // Cells are always rescanned, so no write barrier here. 3198 // Cells are always rescanned, so no write barrier here.
3190 } 3199 }
3191 3200
3192 3201
3193 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { 3202 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) {
3194 ASSERT(ToRegister(instr->context()).is(esi)); 3203 ASSERT(ToRegister(instr->context()).is(esi));
3195 ASSERT(ToRegister(instr->global_object()).is(edx)); 3204 ASSERT(ToRegister(instr->global_object()).is(edx));
3196 ASSERT(ToRegister(instr->value()).is(eax)); 3205 ASSERT(ToRegister(instr->value()).is(eax));
3197 3206
3198 __ mov(ecx, instr->name()); 3207 __ mov(ecx, instr->name());
3199 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3208 Handle<Code> ic = StoreIC::initialize_stub(isolate(),
3200 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3209 instr->strict_mode_flag(),
3201 : isolate()->builtins()->StoreIC_Initialize(); 3210 CONTEXTUAL);
3202 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); 3211 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3203 } 3212 }
3204 3213
3205 3214
3206 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { 3215 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
3207 Register context = ToRegister(instr->context()); 3216 Register context = ToRegister(instr->context());
3208 Register result = ToRegister(instr->result()); 3217 Register result = ToRegister(instr->result());
3209 __ mov(result, ContextOperand(context, instr->slot_index())); 3218 __ mov(result, ContextOperand(context, instr->slot_index()));
3210 3219
3211 if (instr->hydrogen()->RequiresHoleCheck()) { 3220 if (instr->hydrogen()->RequiresHoleCheck()) {
3212 __ cmp(result, factory()->the_hole_value()); 3221 __ cmp(result, factory()->the_hole_value());
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3311 } 3320 }
3312 } 3321 }
3313 3322
3314 3323
3315 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 3324 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3316 ASSERT(ToRegister(instr->context()).is(esi)); 3325 ASSERT(ToRegister(instr->context()).is(esi));
3317 ASSERT(ToRegister(instr->object()).is(edx)); 3326 ASSERT(ToRegister(instr->object()).is(edx));
3318 ASSERT(ToRegister(instr->result()).is(eax)); 3327 ASSERT(ToRegister(instr->result()).is(eax));
3319 3328
3320 __ mov(ecx, instr->name()); 3329 __ mov(ecx, instr->name());
3321 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3330 Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
3322 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3331 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3323 } 3332 }
3324 3333
3325 3334
3326 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { 3335 void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
3327 Register function = ToRegister(instr->function()); 3336 Register function = ToRegister(instr->function());
3328 Register temp = ToRegister(instr->temp()); 3337 Register temp = ToRegister(instr->temp());
3329 Register result = ToRegister(instr->result()); 3338 Register result = ToRegister(instr->result());
3330 3339
3331 // Check that the function really is a function. 3340 // Check that the function really is a function.
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
3635 3644
3636 3645
3637 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3646 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3638 Register receiver = ToRegister(instr->receiver()); 3647 Register receiver = ToRegister(instr->receiver());
3639 Register function = ToRegister(instr->function()); 3648 Register function = ToRegister(instr->function());
3640 Register scratch = ToRegister(instr->temp()); 3649 Register scratch = ToRegister(instr->temp());
3641 3650
3642 // If the receiver is null or undefined, we have to pass the global 3651 // If the receiver is null or undefined, we have to pass the global
3643 // object as a receiver to normal functions. Values have to be 3652 // object as a receiver to normal functions. Values have to be
3644 // passed unchanged to builtins and strict-mode functions. 3653 // passed unchanged to builtins and strict-mode functions.
3645 Label global_object, receiver_ok; 3654 Label receiver_ok, global_object;
3646 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3655 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
3647 3656
3648 // Do not transform the receiver to object for strict mode 3657 // Do not transform the receiver to object for strict mode
3649 // functions. 3658 // functions.
3650 __ mov(scratch, 3659 __ mov(scratch,
3651 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3660 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3652 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset), 3661 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
3653 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 3662 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
3654 __ j(not_equal, &receiver_ok, dist); 3663 __ j(not_equal, &receiver_ok, dist);
3655 3664
3656 // Do not transform the receiver to object for builtins. 3665 // Do not transform the receiver to object for builtins.
3657 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset), 3666 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
3658 1 << SharedFunctionInfo::kNativeBitWithinByte); 3667 1 << SharedFunctionInfo::kNativeBitWithinByte);
3659 __ j(not_equal, &receiver_ok, dist); 3668 __ j(not_equal, &receiver_ok, dist);
3660 3669
3661 // Normal function. Replace undefined or null with global receiver. 3670 // Normal function. Replace undefined or null with global receiver.
3662 __ cmp(receiver, factory()->null_value()); 3671 __ cmp(receiver, factory()->null_value());
3663 __ j(equal, &global_object, Label::kNear); 3672 __ j(equal, &global_object, Label::kNear);
3664 __ cmp(receiver, factory()->undefined_value()); 3673 __ cmp(receiver, factory()->undefined_value());
3665 __ j(equal, &global_object, Label::kNear); 3674 __ j(equal, &global_object, Label::kNear);
3666 3675
3667 // The receiver should be a JS object. 3676 // The receiver should be a JS object.
3668 __ test(receiver, Immediate(kSmiTagMask)); 3677 __ test(receiver, Immediate(kSmiTagMask));
3669 DeoptimizeIf(equal, instr->environment()); 3678 DeoptimizeIf(equal, instr->environment());
3670 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); 3679 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
3671 DeoptimizeIf(below, instr->environment()); 3680 DeoptimizeIf(below, instr->environment());
3672 __ jmp(&receiver_ok, Label::kNear); 3681 __ jmp(&receiver_ok, Label::kNear);
3673 3682
3674 __ bind(&global_object); 3683 __ bind(&global_object);
3675 // TODO(kmillikin): We have a hydrogen value for the global object. See 3684 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset));
3676 // if it's better to use it than to explicitly fetch it from the context
3677 // here.
3678 __ mov(receiver, Operand(ebp, StandardFrameConstants::kContextOffset));
3679 __ mov(receiver, ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
3680 __ mov(receiver, 3685 __ mov(receiver,
3681 FieldOperand(receiver, JSGlobalObject::kGlobalReceiverOffset)); 3686 Operand(receiver, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3687 __ mov(receiver, FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset));
3688
3682 __ bind(&receiver_ok); 3689 __ bind(&receiver_ok);
3683 } 3690 }
3684 3691
3685 3692
3686 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3693 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3687 Register receiver = ToRegister(instr->receiver()); 3694 Register receiver = ToRegister(instr->receiver());
3688 Register function = ToRegister(instr->function()); 3695 Register function = ToRegister(instr->function());
3689 Register length = ToRegister(instr->length()); 3696 Register length = ToRegister(instr->length());
3690 Register elements = ToRegister(instr->elements()); 3697 Register elements = ToRegister(instr->elements());
3691 ASSERT(receiver.is(eax)); // Used for parameter count. 3698 ASSERT(receiver.is(eax)); // Used for parameter count.
(...skipping 21 matching lines...) Expand all
3713 __ j(not_zero, &loop); 3720 __ j(not_zero, &loop);
3714 3721
3715 // Invoke the function. 3722 // Invoke the function.
3716 __ bind(&invoke); 3723 __ bind(&invoke);
3717 ASSERT(instr->HasPointerMap()); 3724 ASSERT(instr->HasPointerMap());
3718 LPointerMap* pointers = instr->pointer_map(); 3725 LPointerMap* pointers = instr->pointer_map();
3719 SafepointGenerator safepoint_generator( 3726 SafepointGenerator safepoint_generator(
3720 this, pointers, Safepoint::kLazyDeopt); 3727 this, pointers, Safepoint::kLazyDeopt);
3721 ParameterCount actual(eax); 3728 ParameterCount actual(eax);
3722 __ InvokeFunction(function, actual, CALL_FUNCTION, 3729 __ InvokeFunction(function, actual, CALL_FUNCTION,
3723 safepoint_generator, CALL_AS_METHOD); 3730 safepoint_generator, CALL_AS_FUNCTION);
3724 } 3731 }
3725 3732
3726 3733
3727 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 3734 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3728 __ int3(); 3735 __ int3();
3729 } 3736 }
3730 3737
3731 3738
3732 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3739 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3733 LOperand* argument = instr->value(); 3740 LOperand* argument = instr->value();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3834 } 3841 }
3835 } 3842 }
3836 3843
3837 3844
3838 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 3845 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3839 ASSERT(ToRegister(instr->result()).is(eax)); 3846 ASSERT(ToRegister(instr->result()).is(eax));
3840 CallKnownFunction(instr->hydrogen()->function(), 3847 CallKnownFunction(instr->hydrogen()->function(),
3841 instr->hydrogen()->formal_parameter_count(), 3848 instr->hydrogen()->formal_parameter_count(),
3842 instr->arity(), 3849 instr->arity(),
3843 instr, 3850 instr,
3844 CALL_AS_METHOD, 3851 CALL_AS_FUNCTION,
3845 EDI_UNINITIALIZED); 3852 EDI_UNINITIALIZED);
3846 } 3853 }
3847 3854
3848 3855
3849 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3856 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3850 Register input_reg = ToRegister(instr->value()); 3857 Register input_reg = ToRegister(instr->value());
3851 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3858 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3852 factory()->heap_number_map()); 3859 factory()->heap_number_map());
3853 DeoptimizeIf(not_equal, instr->environment()); 3860 DeoptimizeIf(not_equal, instr->environment());
3854 3861
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
4195 ASSERT(ToRegister(instr->context()).is(esi)); 4202 ASSERT(ToRegister(instr->context()).is(esi));
4196 ASSERT(ToRegister(instr->function()).is(edi)); 4203 ASSERT(ToRegister(instr->function()).is(edi));
4197 ASSERT(instr->HasPointerMap()); 4204 ASSERT(instr->HasPointerMap());
4198 4205
4199 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 4206 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4200 if (known_function.is_null()) { 4207 if (known_function.is_null()) {
4201 LPointerMap* pointers = instr->pointer_map(); 4208 LPointerMap* pointers = instr->pointer_map();
4202 SafepointGenerator generator( 4209 SafepointGenerator generator(
4203 this, pointers, Safepoint::kLazyDeopt); 4210 this, pointers, Safepoint::kLazyDeopt);
4204 ParameterCount count(instr->arity()); 4211 ParameterCount count(instr->arity());
4205 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 4212 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION);
4206 } else { 4213 } else {
4207 CallKnownFunction(known_function, 4214 CallKnownFunction(known_function,
4208 instr->hydrogen()->formal_parameter_count(), 4215 instr->hydrogen()->formal_parameter_count(),
4209 instr->arity(), 4216 instr->arity(),
4210 instr, 4217 instr,
4211 CALL_AS_METHOD, 4218 CALL_AS_FUNCTION,
4212 EDI_CONTAINS_TARGET); 4219 EDI_CONTAINS_TARGET);
4213 } 4220 }
4214 } 4221 }
4215 4222
4216 4223
4217 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 4224 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
4218 ASSERT(ToRegister(instr->context()).is(esi)); 4225 ASSERT(ToRegister(instr->context()).is(esi));
4219 ASSERT(ToRegister(instr->key()).is(ecx)); 4226 ASSERT(ToRegister(instr->key()).is(ecx));
4220 ASSERT(ToRegister(instr->result()).is(eax)); 4227 ASSERT(ToRegister(instr->result()).is(eax));
4221 4228
4222 int arity = instr->arity(); 4229 int arity = instr->arity();
4223 Handle<Code> ic = 4230 Handle<Code> ic =
4224 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); 4231 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
4225 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4232 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4226 } 4233 }
4227 4234
4228 4235
4229 void LCodeGen::DoCallNamed(LCallNamed* instr) { 4236 void LCodeGen::DoCallNamed(LCallNamed* instr) {
4230 ASSERT(ToRegister(instr->context()).is(esi)); 4237 ASSERT(ToRegister(instr->context()).is(esi));
4231 ASSERT(ToRegister(instr->result()).is(eax)); 4238 ASSERT(ToRegister(instr->result()).is(eax));
4232 4239
4233 int arity = instr->arity(); 4240 int arity = instr->arity();
4234 RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
4235 Handle<Code> ic = 4241 Handle<Code> ic =
4236 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 4242 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_CONTEXTUAL);
4237 __ mov(ecx, instr->name()); 4243 __ mov(ecx, instr->name());
4238 CallCode(ic, mode, instr); 4244 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4239 } 4245 }
4240 4246
4241 4247
4242 void LCodeGen::DoCallFunction(LCallFunction* instr) { 4248 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4243 ASSERT(ToRegister(instr->context()).is(esi)); 4249 ASSERT(ToRegister(instr->context()).is(esi));
4244 ASSERT(ToRegister(instr->function()).is(edi)); 4250 ASSERT(ToRegister(instr->function()).is(edi));
4245 ASSERT(ToRegister(instr->result()).is(eax)); 4251 ASSERT(ToRegister(instr->result()).is(eax));
4246 4252
4247 int arity = instr->arity(); 4253 int arity = instr->arity();
4248 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 4254 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
4249 if (instr->hydrogen()->IsTailCall()) { 4255 if (instr->hydrogen()->IsTailCall()) {
4250 if (NeedsEagerFrame()) __ leave(); 4256 if (NeedsEagerFrame()) __ leave();
4251 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 4257 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
4252 } else { 4258 } else {
4253 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4259 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4254 } 4260 }
4255 } 4261 }
4256 4262
4257 4263
4258 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 4264 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
4259 ASSERT(ToRegister(instr->context()).is(esi)); 4265 ASSERT(ToRegister(instr->context()).is(esi));
4260 ASSERT(ToRegister(instr->result()).is(eax)); 4266 ASSERT(ToRegister(instr->result()).is(eax));
4261 4267
4262 int arity = instr->arity(); 4268 int arity = instr->arity();
4263 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
4264 Handle<Code> ic = 4269 Handle<Code> ic =
4265 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); 4270 isolate()->stub_cache()->ComputeCallInitialize(arity, CONTEXTUAL);
4266 __ mov(ecx, instr->name()); 4271 __ mov(ecx, instr->name());
4267 CallCode(ic, mode, instr); 4272 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4268 } 4273 }
4269 4274
4270 4275
4271 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { 4276 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
4272 ASSERT(ToRegister(instr->result()).is(eax)); 4277 ASSERT(ToRegister(instr->result()).is(eax));
4273 CallKnownFunction(instr->hydrogen()->target(), 4278 CallKnownFunction(instr->hydrogen()->target(),
4274 instr->hydrogen()->formal_parameter_count(), 4279 instr->hydrogen()->formal_parameter_count(),
4275 instr->arity(), 4280 instr->arity(),
4276 instr, 4281 instr,
4277 CALL_AS_FUNCTION, 4282 CALL_AS_FUNCTION,
(...skipping 20 matching lines...) Expand all
4298 ASSERT(ToRegister(instr->constructor()).is(edi)); 4303 ASSERT(ToRegister(instr->constructor()).is(edi));
4299 ASSERT(ToRegister(instr->result()).is(eax)); 4304 ASSERT(ToRegister(instr->result()).is(eax));
4300 4305
4301 __ Set(eax, Immediate(instr->arity())); 4306 __ Set(eax, Immediate(instr->arity()));
4302 __ mov(ebx, instr->hydrogen()->property_cell()); 4307 __ mov(ebx, instr->hydrogen()->property_cell());
4303 ElementsKind kind = instr->hydrogen()->elements_kind(); 4308 ElementsKind kind = instr->hydrogen()->elements_kind();
4304 AllocationSiteOverrideMode override_mode = 4309 AllocationSiteOverrideMode override_mode =
4305 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) 4310 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
4306 ? DISABLE_ALLOCATION_SITES 4311 ? DISABLE_ALLOCATION_SITES
4307 : DONT_OVERRIDE; 4312 : DONT_OVERRIDE;
4308 ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED;
4309 4313
4310 if (instr->arity() == 0) { 4314 if (instr->arity() == 0) {
4311 ArrayNoArgumentConstructorStub stub(kind, context_mode, override_mode); 4315 ArrayNoArgumentConstructorStub stub(kind, override_mode);
4312 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4316 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4313 } else if (instr->arity() == 1) { 4317 } else if (instr->arity() == 1) {
4314 Label done; 4318 Label done;
4315 if (IsFastPackedElementsKind(kind)) { 4319 if (IsFastPackedElementsKind(kind)) {
4316 Label packed_case; 4320 Label packed_case;
4317 // We might need a change here 4321 // We might need a change here
4318 // look at the first argument 4322 // look at the first argument
4319 __ mov(ecx, Operand(esp, 0)); 4323 __ mov(ecx, Operand(esp, 0));
4320 __ test(ecx, ecx); 4324 __ test(ecx, ecx);
4321 __ j(zero, &packed_case, Label::kNear); 4325 __ j(zero, &packed_case, Label::kNear);
4322 4326
4323 ElementsKind holey_kind = GetHoleyElementsKind(kind); 4327 ElementsKind holey_kind = GetHoleyElementsKind(kind);
4324 ArraySingleArgumentConstructorStub stub(holey_kind, context_mode, 4328 ArraySingleArgumentConstructorStub stub(holey_kind, override_mode);
4325 override_mode);
4326 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4329 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4327 __ jmp(&done, Label::kNear); 4330 __ jmp(&done, Label::kNear);
4328 __ bind(&packed_case); 4331 __ bind(&packed_case);
4329 } 4332 }
4330 4333
4331 ArraySingleArgumentConstructorStub stub(kind, context_mode, override_mode); 4334 ArraySingleArgumentConstructorStub stub(kind, override_mode);
4332 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4335 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4333 __ bind(&done); 4336 __ bind(&done);
4334 } else { 4337 } else {
4335 ArrayNArgumentsConstructorStub stub(kind, context_mode, override_mode); 4338 ArrayNArgumentsConstructorStub stub(kind, override_mode);
4336 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); 4339 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
4337 } 4340 }
4338 } 4341 }
4339 4342
4340 4343
4341 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { 4344 void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
4342 ASSERT(ToRegister(instr->context()).is(esi)); 4345 ASSERT(ToRegister(instr->context()).is(esi));
4343 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles()); 4346 CallRuntime(instr->function(), instr->arity(), instr, instr->save_doubles());
4344 } 4347 }
4345 4348
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
4489 } 4492 }
4490 } 4493 }
4491 4494
4492 4495
4493 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { 4496 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
4494 ASSERT(ToRegister(instr->context()).is(esi)); 4497 ASSERT(ToRegister(instr->context()).is(esi));
4495 ASSERT(ToRegister(instr->object()).is(edx)); 4498 ASSERT(ToRegister(instr->object()).is(edx));
4496 ASSERT(ToRegister(instr->value()).is(eax)); 4499 ASSERT(ToRegister(instr->value()).is(eax));
4497 4500
4498 __ mov(ecx, instr->name()); 4501 __ mov(ecx, instr->name());
4499 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 4502 Handle<Code> ic = StoreIC::initialize_stub(isolate(),
4500 ? isolate()->builtins()->StoreIC_Initialize_Strict() 4503 instr->strict_mode_flag(),
4501 : isolate()->builtins()->StoreIC_Initialize(); 4504 NOT_CONTEXTUAL);
4502 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4505 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4503 } 4506 }
4504 4507
4505 4508
4506 void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) { 4509 void LCodeGen::ApplyCheckIf(Condition cc, LBoundsCheck* check) {
4507 if (FLAG_debug_code && check->hydrogen()->skip_check()) { 4510 if (FLAG_debug_code && check->hydrogen()->skip_check()) {
4508 Label done; 4511 Label done;
4509 __ j(NegateCondition(cc), &done, Label::kNear); 4512 __ j(NegateCondition(cc), &done, Label::kNear);
4510 __ int3(); 4513 __ int3();
4511 __ bind(&done); 4514 __ bind(&done);
(...skipping 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after
6363 FixedArray::kHeaderSize - kPointerSize)); 6366 FixedArray::kHeaderSize - kPointerSize));
6364 __ bind(&done); 6367 __ bind(&done);
6365 } 6368 }
6366 6369
6367 6370
6368 #undef __ 6371 #undef __
6369 6372
6370 } } // namespace v8::internal 6373 } } // namespace v8::internal
6371 6374
6372 #endif // V8_TARGET_ARCH_IA32 6375 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698