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

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

Issue 131663003: Make the strict-mode calling convention for contextual calls the default one. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix arm port Created 6 years, 11 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.cc » ('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 3434 matching lines...) Expand 10 before | Expand all | Expand 10 after
3634 3644
3635 3645
3636 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { 3646 void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
3637 Register receiver = ToRegister(instr->receiver()); 3647 Register receiver = ToRegister(instr->receiver());
3638 Register function = ToRegister(instr->function()); 3648 Register function = ToRegister(instr->function());
3639 Register scratch = ToRegister(instr->temp()); 3649 Register scratch = ToRegister(instr->temp());
3640 3650
3641 // 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
3642 // object as a receiver to normal functions. Values have to be 3652 // object as a receiver to normal functions. Values have to be
3643 // passed unchanged to builtins and strict-mode functions. 3653 // passed unchanged to builtins and strict-mode functions.
3644 Label global_object, receiver_ok; 3654 Label receiver_ok, global_object;
3645 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3655 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
3646 3656
3647 // Do not transform the receiver to object for strict mode 3657 // Do not transform the receiver to object for strict mode
3648 // functions. 3658 // functions.
3649 __ mov(scratch, 3659 __ mov(scratch,
3650 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 3660 FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
3651 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset), 3661 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kStrictModeByteOffset),
3652 1 << SharedFunctionInfo::kStrictModeBitWithinByte); 3662 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
3653 __ j(not_equal, &receiver_ok, dist); 3663 __ j(not_equal, &receiver_ok, dist);
3654 3664
3655 // Do not transform the receiver to object for builtins. 3665 // Do not transform the receiver to object for builtins.
3656 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset), 3666 __ test_b(FieldOperand(scratch, SharedFunctionInfo::kNativeByteOffset),
3657 1 << SharedFunctionInfo::kNativeBitWithinByte); 3667 1 << SharedFunctionInfo::kNativeBitWithinByte);
3658 __ j(not_equal, &receiver_ok, dist); 3668 __ j(not_equal, &receiver_ok, dist);
3659 3669
3660 // Normal function. Replace undefined or null with global receiver. 3670 // Normal function. Replace undefined or null with global receiver.
3661 __ cmp(receiver, factory()->null_value()); 3671 __ cmp(receiver, factory()->null_value());
3662 __ j(equal, &global_object, Label::kNear); 3672 __ j(equal, &global_object, Label::kNear);
3663 __ cmp(receiver, factory()->undefined_value()); 3673 __ cmp(receiver, factory()->undefined_value());
3664 __ j(equal, &global_object, Label::kNear); 3674 __ j(equal, &global_object, Label::kNear);
3665 3675
3666 // The receiver should be a JS object. 3676 // The receiver should be a JS object.
3667 __ test(receiver, Immediate(kSmiTagMask)); 3677 __ test(receiver, Immediate(kSmiTagMask));
3668 DeoptimizeIf(equal, instr->environment()); 3678 DeoptimizeIf(equal, instr->environment());
3669 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch); 3679 __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
3670 DeoptimizeIf(below, instr->environment()); 3680 DeoptimizeIf(below, instr->environment());
3671 __ jmp(&receiver_ok, Label::kNear); 3681 __ jmp(&receiver_ok, Label::kNear);
3672 3682
3673 __ bind(&global_object); 3683 __ bind(&global_object);
3674 // TODO(kmillikin): We have a hydrogen value for the global object. See 3684 __ mov(receiver, FieldOperand(function, JSFunction::kContextOffset));
3675 // if it's better to use it than to explicitly fetch it from the context 3685 __ mov(receiver,
3676 // here. 3686 Operand(receiver, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3677 CallStubCompiler::FetchGlobalProxy(masm(), receiver, function); 3687 __ mov(receiver, FieldOperand(receiver, GlobalObject::kGlobalReceiverOffset));
3688
3678 __ bind(&receiver_ok); 3689 __ bind(&receiver_ok);
3679 } 3690 }
3680 3691
3681 3692
3682 void LCodeGen::DoApplyArguments(LApplyArguments* instr) { 3693 void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
3683 Register receiver = ToRegister(instr->receiver()); 3694 Register receiver = ToRegister(instr->receiver());
3684 Register function = ToRegister(instr->function()); 3695 Register function = ToRegister(instr->function());
3685 Register length = ToRegister(instr->length()); 3696 Register length = ToRegister(instr->length());
3686 Register elements = ToRegister(instr->elements()); 3697 Register elements = ToRegister(instr->elements());
3687 ASSERT(receiver.is(eax)); // Used for parameter count. 3698 ASSERT(receiver.is(eax)); // Used for parameter count.
(...skipping 21 matching lines...) Expand all
3709 __ j(not_zero, &loop); 3720 __ j(not_zero, &loop);
3710 3721
3711 // Invoke the function. 3722 // Invoke the function.
3712 __ bind(&invoke); 3723 __ bind(&invoke);
3713 ASSERT(instr->HasPointerMap()); 3724 ASSERT(instr->HasPointerMap());
3714 LPointerMap* pointers = instr->pointer_map(); 3725 LPointerMap* pointers = instr->pointer_map();
3715 SafepointGenerator safepoint_generator( 3726 SafepointGenerator safepoint_generator(
3716 this, pointers, Safepoint::kLazyDeopt); 3727 this, pointers, Safepoint::kLazyDeopt);
3717 ParameterCount actual(eax); 3728 ParameterCount actual(eax);
3718 __ InvokeFunction(function, actual, CALL_FUNCTION, 3729 __ InvokeFunction(function, actual, CALL_FUNCTION,
3719 safepoint_generator, CALL_AS_METHOD); 3730 safepoint_generator, CALL_AS_FUNCTION);
3720 } 3731 }
3721 3732
3722 3733
3723 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { 3734 void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
3724 __ int3(); 3735 __ int3();
3725 } 3736 }
3726 3737
3727 3738
3728 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3739 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3729 LOperand* argument = instr->value(); 3740 LOperand* argument = instr->value();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3830 } 3841 }
3831 } 3842 }
3832 3843
3833 3844
3834 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 3845 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3835 ASSERT(ToRegister(instr->result()).is(eax)); 3846 ASSERT(ToRegister(instr->result()).is(eax));
3836 CallKnownFunction(instr->hydrogen()->function(), 3847 CallKnownFunction(instr->hydrogen()->function(),
3837 instr->hydrogen()->formal_parameter_count(), 3848 instr->hydrogen()->formal_parameter_count(),
3838 instr->arity(), 3849 instr->arity(),
3839 instr, 3850 instr,
3840 CALL_AS_METHOD, 3851 CALL_AS_FUNCTION,
3841 EDI_UNINITIALIZED); 3852 EDI_UNINITIALIZED);
3842 } 3853 }
3843 3854
3844 3855
3845 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3856 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3846 Register input_reg = ToRegister(instr->value()); 3857 Register input_reg = ToRegister(instr->value());
3847 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 3858 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
3848 factory()->heap_number_map()); 3859 factory()->heap_number_map());
3849 DeoptimizeIf(not_equal, instr->environment()); 3860 DeoptimizeIf(not_equal, instr->environment());
3850 3861
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
4191 ASSERT(ToRegister(instr->context()).is(esi)); 4202 ASSERT(ToRegister(instr->context()).is(esi));
4192 ASSERT(ToRegister(instr->function()).is(edi)); 4203 ASSERT(ToRegister(instr->function()).is(edi));
4193 ASSERT(instr->HasPointerMap()); 4204 ASSERT(instr->HasPointerMap());
4194 4205
4195 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 4206 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
4196 if (known_function.is_null()) { 4207 if (known_function.is_null()) {
4197 LPointerMap* pointers = instr->pointer_map(); 4208 LPointerMap* pointers = instr->pointer_map();
4198 SafepointGenerator generator( 4209 SafepointGenerator generator(
4199 this, pointers, Safepoint::kLazyDeopt); 4210 this, pointers, Safepoint::kLazyDeopt);
4200 ParameterCount count(instr->arity()); 4211 ParameterCount count(instr->arity());
4201 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 4212 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION);
4202 } else { 4213 } else {
4203 CallKnownFunction(known_function, 4214 CallKnownFunction(known_function,
4204 instr->hydrogen()->formal_parameter_count(), 4215 instr->hydrogen()->formal_parameter_count(),
4205 instr->arity(), 4216 instr->arity(),
4206 instr, 4217 instr,
4207 CALL_AS_METHOD, 4218 CALL_AS_FUNCTION,
4208 EDI_CONTAINS_TARGET); 4219 EDI_CONTAINS_TARGET);
4209 } 4220 }
4210 } 4221 }
4211 4222
4212 4223
4213 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 4224 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
4214 ASSERT(ToRegister(instr->context()).is(esi)); 4225 ASSERT(ToRegister(instr->context()).is(esi));
4215 ASSERT(ToRegister(instr->key()).is(ecx)); 4226 ASSERT(ToRegister(instr->key()).is(ecx));
4216 ASSERT(ToRegister(instr->result()).is(eax)); 4227 ASSERT(ToRegister(instr->result()).is(eax));
4217 4228
(...skipping 15 matching lines...) Expand all
4233 CallCode(ic, RelocInfo::CODE_TARGET, instr); 4244 CallCode(ic, RelocInfo::CODE_TARGET, instr);
4234 } 4245 }
4235 4246
4236 4247
4237 void LCodeGen::DoCallFunction(LCallFunction* instr) { 4248 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4238 ASSERT(ToRegister(instr->context()).is(esi)); 4249 ASSERT(ToRegister(instr->context()).is(esi));
4239 ASSERT(ToRegister(instr->function()).is(edi)); 4250 ASSERT(ToRegister(instr->function()).is(edi));
4240 ASSERT(ToRegister(instr->result()).is(eax)); 4251 ASSERT(ToRegister(instr->result()).is(eax));
4241 4252
4242 int arity = instr->arity(); 4253 int arity = instr->arity();
4243 CallFunctionFlags flags = 4254 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
4244 instr->hydrogen()->IsContextualCall() ?
4245 RECEIVER_IS_IMPLICIT : NO_CALL_FUNCTION_FLAGS;
4246 CallFunctionStub stub(arity, flags);
4247 if (instr->hydrogen()->IsTailCall()) { 4255 if (instr->hydrogen()->IsTailCall()) {
4248 if (NeedsEagerFrame()) __ leave(); 4256 if (NeedsEagerFrame()) __ leave();
4249 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 4257 __ jmp(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
4250 } else { 4258 } else {
4251 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4259 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4252 } 4260 }
4253 } 4261 }
4254 4262
4255 4263
4256 void LCodeGen::DoCallGlobal(LCallGlobal* instr) { 4264 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
(...skipping 2101 matching lines...) Expand 10 before | Expand all | Expand 10 after
6358 FixedArray::kHeaderSize - kPointerSize)); 6366 FixedArray::kHeaderSize - kPointerSize));
6359 __ bind(&done); 6367 __ bind(&done);
6360 } 6368 }
6361 6369
6362 6370
6363 #undef __ 6371 #undef __
6364 6372
6365 } } // namespace v8::internal 6373 } } // namespace v8::internal
6366 6374
6367 #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.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698