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

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

Issue 132623005: A64: Synchronize with r18642. (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/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 // fp: Caller's frame pointer. 147 // fp: Caller's frame pointer.
148 // lr: Caller's pc. 148 // lr: Caller's pc.
149 149
150 // Classic mode functions and builtins need to replace the receiver with the 150 // Classic mode functions and builtins need to replace the receiver with the
151 // global proxy when called as functions (without an explicit receiver 151 // global proxy when called as functions (without an explicit receiver
152 // object). 152 // object).
153 if (info_->this_has_uses() && 153 if (info_->this_has_uses() &&
154 info_->is_classic_mode() && 154 info_->is_classic_mode() &&
155 !info_->is_native()) { 155 !info_->is_native()) {
156 Label ok; 156 Label ok;
157 __ cmp(r5, Operand::Zero());
158 __ b(eq, &ok);
159
160 int receiver_offset = info_->scope()->num_parameters() * kPointerSize; 157 int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
161 __ ldr(r2, MemOperand(sp, receiver_offset)); 158 __ ldr(r2, MemOperand(sp, receiver_offset));
162 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 159 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
163 __ b(ne, &ok); 160 __ b(ne, &ok);
164 161
165 __ ldr(r2, GlobalObjectOperand()); 162 __ ldr(r2, GlobalObjectOperand());
166 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); 163 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
167 164
168 __ str(r2, MemOperand(sp, receiver_offset)); 165 __ str(r2, MemOperand(sp, receiver_offset));
169 166
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 TargetAddressStorageMode storage_mode) { 713 TargetAddressStorageMode storage_mode) {
717 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode); 714 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode);
718 } 715 }
719 716
720 717
721 void LCodeGen::CallCodeGeneric(Handle<Code> code, 718 void LCodeGen::CallCodeGeneric(Handle<Code> code,
722 RelocInfo::Mode mode, 719 RelocInfo::Mode mode,
723 LInstruction* instr, 720 LInstruction* instr,
724 SafepointMode safepoint_mode, 721 SafepointMode safepoint_mode,
725 TargetAddressStorageMode storage_mode) { 722 TargetAddressStorageMode storage_mode) {
726 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
727 ASSERT(instr != NULL); 723 ASSERT(instr != NULL);
728 // Block literal pool emission to ensure nop indicating no inlined smi code 724 // Block literal pool emission to ensure nop indicating no inlined smi code
729 // is in the correct position. 725 // is in the correct position.
730 Assembler::BlockConstPoolScope block_const_pool(masm()); 726 Assembler::BlockConstPoolScope block_const_pool(masm());
731 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); 727 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode);
732 RecordSafepointWithLazyDeopt(instr, safepoint_mode); 728 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
733 729
734 // Signal that we don't inline smi code before these stubs in the 730 // Signal that we don't inline smi code before these stubs in the
735 // optimizing code generator. 731 // optimizing code generator.
736 if (code->kind() == Code::BINARY_OP_IC || 732 if (code->kind() == Code::BINARY_OP_IC ||
(...skipping 2764 matching lines...) Expand 10 before | Expand all | Expand 10 after
3501 // Deoptimize if the receiver is not a JS object. 3497 // Deoptimize if the receiver is not a JS object.
3502 __ SmiTst(receiver); 3498 __ SmiTst(receiver);
3503 DeoptimizeIf(eq, instr->environment()); 3499 DeoptimizeIf(eq, instr->environment());
3504 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE); 3500 __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
3505 DeoptimizeIf(lt, instr->environment()); 3501 DeoptimizeIf(lt, instr->environment());
3506 __ b(&result_in_receiver); 3502 __ b(&result_in_receiver);
3507 3503
3508 __ bind(&global_object); 3504 __ bind(&global_object);
3509 __ ldr(receiver, FieldMemOperand(function, JSFunction::kContextOffset)); 3505 __ ldr(receiver, FieldMemOperand(function, JSFunction::kContextOffset));
3510 __ ldr(receiver, 3506 __ ldr(receiver,
3511 ContextOperand(receiver, 3507 ContextOperand(receiver, Context::GLOBAL_OBJECT_INDEX));
3512 Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
3513 __ ldr(receiver, 3508 __ ldr(receiver,
3514 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); 3509 FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset));
3515 3510
3516 if (result.is(receiver)) { 3511 if (result.is(receiver)) {
3517 __ bind(&result_in_receiver); 3512 __ bind(&result_in_receiver);
3518 } else { 3513 } else {
3519 Label result_ok; 3514 Label result_ok;
3520 __ b(&result_ok); 3515 __ b(&result_ok);
3521 __ bind(&result_in_receiver); 3516 __ bind(&result_in_receiver);
3522 __ mov(result, receiver); 3517 __ mov(result, receiver);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 __ b(ne, &loop); 3556 __ b(ne, &loop);
3562 3557
3563 __ bind(&invoke); 3558 __ bind(&invoke);
3564 ASSERT(instr->HasPointerMap()); 3559 ASSERT(instr->HasPointerMap());
3565 LPointerMap* pointers = instr->pointer_map(); 3560 LPointerMap* pointers = instr->pointer_map();
3566 SafepointGenerator safepoint_generator( 3561 SafepointGenerator safepoint_generator(
3567 this, pointers, Safepoint::kLazyDeopt); 3562 this, pointers, Safepoint::kLazyDeopt);
3568 // The number of arguments is stored in receiver which is r0, as expected 3563 // The number of arguments is stored in receiver which is r0, as expected
3569 // by InvokeFunction. 3564 // by InvokeFunction.
3570 ParameterCount actual(receiver); 3565 ParameterCount actual(receiver);
3571 __ InvokeFunction(function, actual, CALL_FUNCTION, 3566 __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
3572 safepoint_generator, CALL_AS_FUNCTION);
3573 } 3567 }
3574 3568
3575 3569
3576 void LCodeGen::DoPushArgument(LPushArgument* instr) { 3570 void LCodeGen::DoPushArgument(LPushArgument* instr) {
3577 LOperand* argument = instr->value(); 3571 LOperand* argument = instr->value();
3578 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { 3572 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
3579 Abort(kDoPushArgumentNotImplementedForDoubleType); 3573 Abort(kDoPushArgumentNotImplementedForDoubleType);
3580 } else { 3574 } else {
3581 Register argument_reg = EmitLoadRegister(argument, ip); 3575 Register argument_reg = EmitLoadRegister(argument, ip);
3582 __ push(argument_reg); 3576 __ push(argument_reg);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 Register global = ToRegister(instr->global_object()); 3631 Register global = ToRegister(instr->global_object());
3638 Register result = ToRegister(instr->result()); 3632 Register result = ToRegister(instr->result());
3639 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); 3633 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset));
3640 } 3634 }
3641 3635
3642 3636
3643 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, 3637 void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
3644 int formal_parameter_count, 3638 int formal_parameter_count,
3645 int arity, 3639 int arity,
3646 LInstruction* instr, 3640 LInstruction* instr,
3647 CallKind call_kind,
3648 R1State r1_state) { 3641 R1State r1_state) {
3649 bool dont_adapt_arguments = 3642 bool dont_adapt_arguments =
3650 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; 3643 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3651 bool can_invoke_directly = 3644 bool can_invoke_directly =
3652 dont_adapt_arguments || formal_parameter_count == arity; 3645 dont_adapt_arguments || formal_parameter_count == arity;
3653 3646
3654 LPointerMap* pointers = instr->pointer_map(); 3647 LPointerMap* pointers = instr->pointer_map();
3655 3648
3656 if (can_invoke_directly) { 3649 if (can_invoke_directly) {
3657 if (r1_state == R1_UNINITIALIZED) { 3650 if (r1_state == R1_UNINITIALIZED) {
3658 __ Move(r1, function); 3651 __ Move(r1, function);
3659 } 3652 }
3660 3653
3661 // Change context. 3654 // Change context.
3662 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 3655 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
3663 3656
3664 // Set r0 to arguments count if adaption is not needed. Assumes that r0 3657 // Set r0 to arguments count if adaption is not needed. Assumes that r0
3665 // is available to write to at this point. 3658 // is available to write to at this point.
3666 if (dont_adapt_arguments) { 3659 if (dont_adapt_arguments) {
3667 __ mov(r0, Operand(arity)); 3660 __ mov(r0, Operand(arity));
3668 } 3661 }
3669 3662
3670 // Invoke function. 3663 // Invoke function.
3671 __ SetCallKind(r5, call_kind);
3672 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 3664 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
3673 __ Call(ip); 3665 __ Call(ip);
3674 3666
3675 // Set up deoptimization. 3667 // Set up deoptimization.
3676 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 3668 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
3677 } else { 3669 } else {
3678 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3670 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3679 ParameterCount count(arity); 3671 ParameterCount count(arity);
3680 ParameterCount expected(formal_parameter_count); 3672 ParameterCount expected(formal_parameter_count);
3681 __ InvokeFunction( 3673 __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator);
3682 function, expected, count, CALL_FUNCTION, generator, call_kind);
3683 } 3674 }
3684 } 3675 }
3685 3676
3686 3677
3687 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3688 ASSERT(ToRegister(instr->result()).is(r0));
3689 CallKnownFunction(instr->hydrogen()->function(),
3690 instr->hydrogen()->formal_parameter_count(),
3691 instr->arity(),
3692 instr,
3693 CALL_AS_FUNCTION,
3694 R1_UNINITIALIZED);
3695 }
3696
3697
3698 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { 3678 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3699 ASSERT(instr->context() != NULL); 3679 ASSERT(instr->context() != NULL);
3700 ASSERT(ToRegister(instr->context()).is(cp)); 3680 ASSERT(ToRegister(instr->context()).is(cp));
3701 Register input = ToRegister(instr->value()); 3681 Register input = ToRegister(instr->value());
3702 Register result = ToRegister(instr->result()); 3682 Register result = ToRegister(instr->result());
3703 Register scratch = scratch0(); 3683 Register scratch = scratch0();
3704 3684
3705 // Deoptimize if not a heap number. 3685 // Deoptimize if not a heap number.
3706 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3686 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3707 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3687 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
3961 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3941 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3962 ASSERT(ToRegister(instr->context()).is(cp)); 3942 ASSERT(ToRegister(instr->context()).is(cp));
3963 ASSERT(ToRegister(instr->function()).is(r1)); 3943 ASSERT(ToRegister(instr->function()).is(r1));
3964 ASSERT(instr->HasPointerMap()); 3944 ASSERT(instr->HasPointerMap());
3965 3945
3966 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); 3946 Handle<JSFunction> known_function = instr->hydrogen()->known_function();
3967 if (known_function.is_null()) { 3947 if (known_function.is_null()) {
3968 LPointerMap* pointers = instr->pointer_map(); 3948 LPointerMap* pointers = instr->pointer_map();
3969 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3949 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3970 ParameterCount count(instr->arity()); 3950 ParameterCount count(instr->arity());
3971 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_FUNCTION); 3951 __ InvokeFunction(r1, count, CALL_FUNCTION, generator);
3972 } else { 3952 } else {
3973 CallKnownFunction(known_function, 3953 CallKnownFunction(known_function,
3974 instr->hydrogen()->formal_parameter_count(), 3954 instr->hydrogen()->formal_parameter_count(),
3975 instr->arity(), 3955 instr->arity(),
3976 instr, 3956 instr,
3977 CALL_AS_FUNCTION,
3978 R1_CONTAINS_TARGET); 3957 R1_CONTAINS_TARGET);
3979 } 3958 }
3980 } 3959 }
3981 3960
3982 3961
3983 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 3962 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
3984 ASSERT(ToRegister(instr->context()).is(cp));
3985 ASSERT(ToRegister(instr->result()).is(r0)); 3963 ASSERT(ToRegister(instr->result()).is(r0));
3986 3964
3987 int arity = instr->arity(); 3965 LPointerMap* pointers = instr->pointer_map();
3988 Handle<Code> ic = 3966 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3989 isolate()->stub_cache()->ComputeKeyedCallInitialize(arity); 3967
3990 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); 3968 if (instr->target()->IsConstantOperand()) {
3969 LConstantOperand* target = LConstantOperand::cast(instr->target());
3970 Handle<Code> code = Handle<Code>::cast(ToHandle(target));
3971 generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
3972 PlatformCallInterfaceDescriptor* call_descriptor =
3973 instr->descriptor()->platform_specific_descriptor();
3974 __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al,
3975 call_descriptor->storage_mode());
3976 } else {
3977 ASSERT(instr->target()->IsRegister());
3978 Register target = ToRegister(instr->target());
3979 generator.BeforeCall(__ CallSize(target));
3980 __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
3981 __ Call(target);
3982 }
3983 generator.AfterCall();
3991 } 3984 }
3992 3985
3993 3986
3994 void LCodeGen::DoCallNamed(LCallNamed* instr) { 3987 void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
3995 ASSERT(ToRegister(instr->context()).is(cp)); 3988 ASSERT(ToRegister(instr->function()).is(r1));
3996 ASSERT(ToRegister(instr->result()).is(r0)); 3989 ASSERT(ToRegister(instr->result()).is(r0));
3997 3990
3998 int arity = instr->arity(); 3991 if (instr->hydrogen()->pass_argument_count()) {
3999 Handle<Code> ic = 3992 __ mov(r0, Operand(instr->arity()));
4000 isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_CONTEXTUAL); 3993 }
4001 __ mov(r2, Operand(instr->name())); 3994
4002 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); 3995 // Change context.
3996 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
3997
3998 // Load the code entry address
3999 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
4000 __ Call(ip);
4001
4002 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
4003 } 4003 }
4004 4004
4005 4005
4006 void LCodeGen::DoCallFunction(LCallFunction* instr) { 4006 void LCodeGen::DoCallFunction(LCallFunction* instr) {
4007 ASSERT(ToRegister(instr->context()).is(cp)); 4007 ASSERT(ToRegister(instr->context()).is(cp));
4008 ASSERT(ToRegister(instr->function()).is(r1)); 4008 ASSERT(ToRegister(instr->function()).is(r1));
4009 ASSERT(ToRegister(instr->result()).is(r0)); 4009 ASSERT(ToRegister(instr->result()).is(r0));
4010 4010
4011 int arity = instr->arity(); 4011 int arity = instr->arity();
4012 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS); 4012 CallFunctionStub stub(arity, NO_CALL_FUNCTION_FLAGS);
4013 if (instr->hydrogen()->IsTailCall()) { 4013 if (instr->hydrogen()->IsTailCall()) {
4014 if (NeedsEagerFrame()) __ mov(sp, fp); 4014 if (NeedsEagerFrame()) __ mov(sp, fp);
4015 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 4015 __ Jump(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
4016 } else { 4016 } else {
4017 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4017 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4018 } 4018 }
4019 } 4019 }
4020 4020
4021 4021
4022 void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
4023 ASSERT(ToRegister(instr->context()).is(cp));
4024 ASSERT(ToRegister(instr->result()).is(r0));
4025
4026 int arity = instr->arity();
4027 Handle<Code> ic =
4028 isolate()->stub_cache()->ComputeCallInitialize(arity, CONTEXTUAL);
4029 __ mov(r2, Operand(instr->name()));
4030 CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
4031 }
4032
4033
4034 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) {
4035 ASSERT(ToRegister(instr->result()).is(r0));
4036 CallKnownFunction(instr->hydrogen()->target(),
4037 instr->hydrogen()->formal_parameter_count(),
4038 instr->arity(),
4039 instr,
4040 CALL_AS_FUNCTION,
4041 R1_UNINITIALIZED);
4042 }
4043
4044
4045 void LCodeGen::DoCallNew(LCallNew* instr) { 4022 void LCodeGen::DoCallNew(LCallNew* instr) {
4046 ASSERT(ToRegister(instr->context()).is(cp)); 4023 ASSERT(ToRegister(instr->context()).is(cp));
4047 ASSERT(ToRegister(instr->constructor()).is(r1)); 4024 ASSERT(ToRegister(instr->constructor()).is(r1));
4048 ASSERT(ToRegister(instr->result()).is(r0)); 4025 ASSERT(ToRegister(instr->result()).is(r0));
4049 4026
4050 __ mov(r0, Operand(instr->arity())); 4027 __ mov(r0, Operand(instr->arity()));
4051 // No cell in r2 for construct type feedback in optimized code 4028 // No cell in r2 for construct type feedback in optimized code
4052 Handle<Object> undefined_value(isolate()->factory()->undefined_value()); 4029 Handle<Object> undefined_value(isolate()->factory()->undefined_value());
4053 __ mov(r2, Operand(undefined_value)); 4030 __ mov(r2, Operand(undefined_value));
4054 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 4031 CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 } 5154 }
5178 DeoptimizeIf(ne, instr->environment()); 5155 DeoptimizeIf(ne, instr->environment());
5179 } 5156 }
5180 5157
5181 5158
5182 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { 5159 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
5183 { 5160 {
5184 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 5161 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
5185 __ push(object); 5162 __ push(object);
5186 __ mov(cp, Operand::Zero()); 5163 __ mov(cp, Operand::Zero());
5187 __ CallRuntimeSaveDoubles(Runtime::kMigrateInstance); 5164 __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
5188 RecordSafepointWithRegisters( 5165 RecordSafepointWithRegisters(
5189 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); 5166 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
5190 __ StoreToSafepointRegisterSlot(r0, scratch0()); 5167 __ StoreToSafepointRegisterSlot(r0, scratch0());
5191 } 5168 }
5192 __ tst(scratch0(), Operand(kSmiTagMask)); 5169 __ tst(scratch0(), Operand(kSmiTagMask));
5193 DeoptimizeIf(eq, instr->environment()); 5170 DeoptimizeIf(eq, instr->environment());
5194 } 5171 }
5195 5172
5196 5173
5197 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { 5174 void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after
5594 __ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 5571 __ cmp(temp2, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
5595 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset), eq); 5572 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset), eq);
5596 5573
5597 // Check the marker in the calling frame. 5574 // Check the marker in the calling frame.
5598 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 5575 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
5599 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5576 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5600 } 5577 }
5601 5578
5602 5579
5603 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { 5580 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
5604 if (info()->IsStub()) return; 5581 if (!info()->IsStub()) {
5605 // Ensure that we have enough space after the previous lazy-bailout 5582 // Ensure that we have enough space after the previous lazy-bailout
5606 // instruction for patching the code here. 5583 // instruction for patching the code here.
5607 int current_pc = masm()->pc_offset(); 5584 int current_pc = masm()->pc_offset();
5608 if (current_pc < last_lazy_deopt_pc_ + space_needed) { 5585 if (current_pc < last_lazy_deopt_pc_ + space_needed) {
5609 // Block literal pool emission for duration of padding. 5586 // Block literal pool emission for duration of padding.
5610 Assembler::BlockConstPoolScope block_const_pool(masm()); 5587 Assembler::BlockConstPoolScope block_const_pool(masm());
5611 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; 5588 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
5612 ASSERT_EQ(0, padding_size % Assembler::kInstrSize); 5589 ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
5613 while (padding_size > 0) { 5590 while (padding_size > 0) {
5614 __ nop(); 5591 __ nop();
5615 padding_size -= Assembler::kInstrSize; 5592 padding_size -= Assembler::kInstrSize;
5593 }
5616 } 5594 }
5617 } 5595 }
5596 last_lazy_deopt_pc_ = masm()->pc_offset();
5618 } 5597 }
5619 5598
5620 5599
5621 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 5600 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5622 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 5601 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5623 last_lazy_deopt_pc_ = masm()->pc_offset();
5624 ASSERT(instr->HasEnvironment()); 5602 ASSERT(instr->HasEnvironment());
5625 LEnvironment* env = instr->environment(); 5603 LEnvironment* env = instr->environment();
5626 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5604 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5627 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5605 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5628 } 5606 }
5629 5607
5630 5608
5631 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5609 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5632 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5610 Deoptimizer::BailoutType type = instr->hydrogen()->type();
5633 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the 5611 // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5688 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 5666 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
5689 __ cmp(sp, Operand(ip)); 5667 __ cmp(sp, Operand(ip));
5690 __ b(hs, &done); 5668 __ b(hs, &done);
5691 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); 5669 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize);
5692 ASSERT(instr->context()->IsRegister()); 5670 ASSERT(instr->context()->IsRegister());
5693 ASSERT(ToRegister(instr->context()).is(cp)); 5671 ASSERT(ToRegister(instr->context()).is(cp));
5694 CallCode(isolate()->builtins()->StackCheck(), 5672 CallCode(isolate()->builtins()->StackCheck(),
5695 RelocInfo::CODE_TARGET, 5673 RelocInfo::CODE_TARGET,
5696 instr); 5674 instr);
5697 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 5675 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5698 last_lazy_deopt_pc_ = masm()->pc_offset();
5699 __ bind(&done); 5676 __ bind(&done);
5700 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5677 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5701 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5678 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5702 } else { 5679 } else {
5703 ASSERT(instr->hydrogen()->is_backwards_branch()); 5680 ASSERT(instr->hydrogen()->is_backwards_branch());
5704 // Perform stack overflow check if this goto needs it before jumping. 5681 // Perform stack overflow check if this goto needs it before jumping.
5705 DeferredStackCheck* deferred_stack_check = 5682 DeferredStackCheck* deferred_stack_check =
5706 new(zone()) DeferredStackCheck(this, instr); 5683 new(zone()) DeferredStackCheck(this, instr);
5707 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 5684 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
5708 __ cmp(sp, Operand(ip)); 5685 __ cmp(sp, Operand(ip));
5709 __ b(lo, deferred_stack_check->entry()); 5686 __ b(lo, deferred_stack_check->entry());
5710 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); 5687 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5711 last_lazy_deopt_pc_ = masm()->pc_offset();
5712 __ bind(instr->done_label()); 5688 __ bind(instr->done_label());
5713 deferred_stack_check->SetExit(instr->done_label()); 5689 deferred_stack_check->SetExit(instr->done_label());
5714 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5690 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5715 // Don't record a deoptimization index for the safepoint here. 5691 // Don't record a deoptimization index for the safepoint here.
5716 // This will be done explicitly when emitting call and the safepoint in 5692 // This will be done explicitly when emitting call and the safepoint in
5717 // the deferred code. 5693 // the deferred code.
5718 } 5694 }
5719 } 5695 }
5720 5696
5721 5697
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
5824 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5800 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5825 __ ldr(result, FieldMemOperand(scratch, 5801 __ ldr(result, FieldMemOperand(scratch,
5826 FixedArray::kHeaderSize - kPointerSize)); 5802 FixedArray::kHeaderSize - kPointerSize));
5827 __ bind(&done); 5803 __ bind(&done);
5828 } 5804 }
5829 5805
5830 5806
5831 #undef __ 5807 #undef __
5832 5808
5833 } } // namespace v8::internal 5809 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698