OLD | NEW |
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 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 // values on the stack that represent the arguments. This needs to be | 628 // values on the stack that represent the arguments. This needs to be |
629 // kept in sync with the LArgumentsElements implementation. | 629 // kept in sync with the LArgumentsElements implementation. |
630 *pushed_arguments_index = -environment->parameter_count(); | 630 *pushed_arguments_index = -environment->parameter_count(); |
631 *pushed_arguments_count = environment->parameter_count(); | 631 *pushed_arguments_count = environment->parameter_count(); |
632 | 632 |
633 WriteTranslation(environment->outer(), | 633 WriteTranslation(environment->outer(), |
634 translation, | 634 translation, |
635 pushed_arguments_index, | 635 pushed_arguments_index, |
636 pushed_arguments_count); | 636 pushed_arguments_count); |
637 bool has_closure_id = !info()->closure().is_null() && | 637 bool has_closure_id = !info()->closure().is_null() && |
638 *info()->closure() != *environment->closure(); | 638 !info()->closure().is_identical_to(environment->closure()); |
639 int closure_id = has_closure_id | 639 int closure_id = has_closure_id |
640 ? DefineDeoptimizationLiteral(environment->closure()) | 640 ? DefineDeoptimizationLiteral(environment->closure()) |
641 : Translation::kSelfLiteralId; | 641 : Translation::kSelfLiteralId; |
642 switch (environment->frame_type()) { | 642 switch (environment->frame_type()) { |
643 case JS_FUNCTION: | 643 case JS_FUNCTION: |
644 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 644 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
645 break; | 645 break; |
646 case JS_CONSTRUCT: | 646 case JS_CONSTRUCT: |
647 translation->BeginConstructStubFrame(closure_id, translation_size); | 647 translation->BeginConstructStubFrame(closure_id, translation_size); |
648 break; | 648 break; |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 Handle<DeoptimizationInputData> data = | 995 Handle<DeoptimizationInputData> data = |
996 factory()->NewDeoptimizationInputData(length, TENURED); | 996 factory()->NewDeoptimizationInputData(length, TENURED); |
997 | 997 |
998 Handle<ByteArray> translations = | 998 Handle<ByteArray> translations = |
999 translations_.CreateByteArray(isolate()->factory()); | 999 translations_.CreateByteArray(isolate()->factory()); |
1000 data->SetTranslationByteArray(*translations); | 1000 data->SetTranslationByteArray(*translations); |
1001 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 1001 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
1002 | 1002 |
1003 Handle<FixedArray> literals = | 1003 Handle<FixedArray> literals = |
1004 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 1004 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
1005 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 1005 { ALLOW_HANDLE_DEREF(isolate(), |
1006 literals->set(i, *deoptimization_literals_[i]); | 1006 "copying a ZoneList of handles into a FixedArray"); |
| 1007 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 1008 literals->set(i, *deoptimization_literals_[i]); |
| 1009 } |
| 1010 data->SetLiteralArray(*literals); |
1007 } | 1011 } |
1008 data->SetLiteralArray(*literals); | |
1009 | 1012 |
1010 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 1013 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
1011 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 1014 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
1012 | 1015 |
1013 // Populate the deoptimization entries. | 1016 // Populate the deoptimization entries. |
1014 for (int i = 0; i < length; i++) { | 1017 for (int i = 0; i < length; i++) { |
1015 LEnvironment* env = deoptimizations_[i]; | 1018 LEnvironment* env = deoptimizations_[i]; |
1016 data->SetAstId(i, env->ast_id()); | 1019 data->SetAstId(i, env->ast_id()); |
1017 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 1020 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
1018 data->SetArgumentsStackHeight(i, | 1021 data->SetArgumentsStackHeight(i, |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1780 } | 1783 } |
1781 } | 1784 } |
1782 } | 1785 } |
1783 } | 1786 } |
1784 } | 1787 } |
1785 | 1788 |
1786 | 1789 |
1787 void LCodeGen::DoConstantT(LConstantT* instr) { | 1790 void LCodeGen::DoConstantT(LConstantT* instr) { |
1788 Register reg = ToRegister(instr->result()); | 1791 Register reg = ToRegister(instr->result()); |
1789 Handle<Object> handle = instr->value(); | 1792 Handle<Object> handle = instr->value(); |
| 1793 ALLOW_HANDLE_DEREF(isolate(), "smi check"); |
1790 if (handle->IsHeapObject()) { | 1794 if (handle->IsHeapObject()) { |
1791 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); | 1795 __ LoadHeapObject(reg, Handle<HeapObject>::cast(handle)); |
1792 } else { | 1796 } else { |
1793 __ Set(reg, Immediate(handle)); | 1797 __ Set(reg, Immediate(handle)); |
1794 } | 1798 } |
1795 } | 1799 } |
1796 | 1800 |
1797 | 1801 |
1798 void LCodeGen::DoFixedArrayBaseLength( | 1802 void LCodeGen::DoFixedArrayBaseLength( |
1799 LFixedArrayBaseLength* instr) { | 1803 LFixedArrayBaseLength* instr) { |
(...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2999 } | 3003 } |
3000 __ mov(result, factory()->undefined_value()); | 3004 __ mov(result, factory()->undefined_value()); |
3001 } | 3005 } |
3002 } | 3006 } |
3003 | 3007 |
3004 | 3008 |
3005 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { | 3009 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
3006 ASSERT(!operand->IsDoubleRegister()); | 3010 ASSERT(!operand->IsDoubleRegister()); |
3007 if (operand->IsConstantOperand()) { | 3011 if (operand->IsConstantOperand()) { |
3008 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); | 3012 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); |
| 3013 ALLOW_HANDLE_DEREF(isolate(), "smi check"); |
3009 if (object->IsSmi()) { | 3014 if (object->IsSmi()) { |
3010 __ Push(Handle<Smi>::cast(object)); | 3015 __ Push(Handle<Smi>::cast(object)); |
3011 } else { | 3016 } else { |
3012 __ PushHeapObject(Handle<HeapObject>::cast(object)); | 3017 __ PushHeapObject(Handle<HeapObject>::cast(object)); |
3013 } | 3018 } |
3014 } else if (operand->IsRegister()) { | 3019 } else if (operand->IsRegister()) { |
3015 __ push(ToRegister(operand)); | 3020 __ push(ToRegister(operand)); |
3016 } else { | 3021 } else { |
3017 __ push(ToOperand(operand)); | 3022 __ push(ToOperand(operand)); |
3018 } | 3023 } |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3583 | 3588 |
3584 | 3589 |
3585 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 3590 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
3586 Register global = ToRegister(instr->global()); | 3591 Register global = ToRegister(instr->global()); |
3587 Register result = ToRegister(instr->result()); | 3592 Register result = ToRegister(instr->result()); |
3588 __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); | 3593 __ mov(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); |
3589 } | 3594 } |
3590 | 3595 |
3591 | 3596 |
3592 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3597 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
| 3598 int formal_parameter_count, |
3593 int arity, | 3599 int arity, |
3594 LInstruction* instr, | 3600 LInstruction* instr, |
3595 CallKind call_kind, | 3601 CallKind call_kind, |
3596 EDIState edi_state) { | 3602 EDIState edi_state) { |
3597 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || | 3603 bool dont_adapt_arguments = |
3598 function->shared()->formal_parameter_count() == arity; | 3604 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3605 bool can_invoke_directly = |
| 3606 dont_adapt_arguments || formal_parameter_count == arity; |
3599 | 3607 |
3600 LPointerMap* pointers = instr->pointer_map(); | 3608 LPointerMap* pointers = instr->pointer_map(); |
3601 RecordPosition(pointers->position()); | 3609 RecordPosition(pointers->position()); |
3602 | 3610 |
3603 if (can_invoke_directly) { | 3611 if (can_invoke_directly) { |
3604 if (edi_state == EDI_UNINITIALIZED) { | 3612 if (edi_state == EDI_UNINITIALIZED) { |
3605 __ LoadHeapObject(edi, function); | 3613 __ LoadHeapObject(edi, function); |
3606 } | 3614 } |
3607 | 3615 |
3608 // Change context. | 3616 // Change context. |
3609 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 3617 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
3610 | 3618 |
3611 // Set eax to arguments count if adaption is not needed. Assumes that eax | 3619 // Set eax to arguments count if adaption is not needed. Assumes that eax |
3612 // is available to write to at this point. | 3620 // is available to write to at this point. |
3613 if (!function->NeedsArgumentsAdaption()) { | 3621 if (dont_adapt_arguments) { |
3614 __ mov(eax, arity); | 3622 __ mov(eax, arity); |
3615 } | 3623 } |
3616 | 3624 |
3617 // Invoke function directly. | 3625 // Invoke function directly. |
3618 __ SetCallKind(ecx, call_kind); | 3626 __ SetCallKind(ecx, call_kind); |
3619 if (*function == *info()->closure()) { | 3627 if (function.is_identical_to(info()->closure())) { |
3620 __ CallSelf(); | 3628 __ CallSelf(); |
3621 } else { | 3629 } else { |
3622 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 3630 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
3623 } | 3631 } |
3624 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 3632 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
3625 } else { | 3633 } else { |
3626 // We need to adapt arguments. | 3634 // We need to adapt arguments. |
3627 SafepointGenerator generator( | 3635 SafepointGenerator generator( |
3628 this, pointers, Safepoint::kLazyDeopt); | 3636 this, pointers, Safepoint::kLazyDeopt); |
3629 ParameterCount count(arity); | 3637 ParameterCount count(arity); |
3630 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); | 3638 ParameterCount expected(formal_parameter_count); |
| 3639 __ InvokeFunction( |
| 3640 function, expected, count, CALL_FUNCTION, generator, call_kind); |
3631 } | 3641 } |
3632 } | 3642 } |
3633 | 3643 |
3634 | 3644 |
3635 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3645 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
3636 ASSERT(ToRegister(instr->result()).is(eax)); | 3646 ASSERT(ToRegister(instr->result()).is(eax)); |
3637 CallKnownFunction(instr->function(), | 3647 CallKnownFunction(instr->hydrogen()->function(), |
| 3648 instr->hydrogen()->formal_parameter_count(), |
3638 instr->arity(), | 3649 instr->arity(), |
3639 instr, | 3650 instr, |
3640 CALL_AS_METHOD, | 3651 CALL_AS_METHOD, |
3641 EDI_UNINITIALIZED); | 3652 EDI_UNINITIALIZED); |
3642 } | 3653 } |
3643 | 3654 |
3644 | 3655 |
3645 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3656 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3646 Register input_reg = ToRegister(instr->value()); | 3657 Register input_reg = ToRegister(instr->value()); |
3647 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 3658 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4089 TranscendentalCacheStub::UNTAGGED); | 4100 TranscendentalCacheStub::UNTAGGED); |
4090 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4101 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
4091 } | 4102 } |
4092 | 4103 |
4093 | 4104 |
4094 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 4105 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
4095 ASSERT(ToRegister(instr->context()).is(esi)); | 4106 ASSERT(ToRegister(instr->context()).is(esi)); |
4096 ASSERT(ToRegister(instr->function()).is(edi)); | 4107 ASSERT(ToRegister(instr->function()).is(edi)); |
4097 ASSERT(instr->HasPointerMap()); | 4108 ASSERT(instr->HasPointerMap()); |
4098 | 4109 |
4099 if (instr->known_function().is_null()) { | 4110 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 4111 if (known_function.is_null()) { |
4100 LPointerMap* pointers = instr->pointer_map(); | 4112 LPointerMap* pointers = instr->pointer_map(); |
4101 RecordPosition(pointers->position()); | 4113 RecordPosition(pointers->position()); |
4102 SafepointGenerator generator( | 4114 SafepointGenerator generator( |
4103 this, pointers, Safepoint::kLazyDeopt); | 4115 this, pointers, Safepoint::kLazyDeopt); |
4104 ParameterCount count(instr->arity()); | 4116 ParameterCount count(instr->arity()); |
4105 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 4117 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
4106 } else { | 4118 } else { |
4107 CallKnownFunction(instr->known_function(), | 4119 CallKnownFunction(known_function, |
| 4120 instr->hydrogen()->formal_parameter_count(), |
4108 instr->arity(), | 4121 instr->arity(), |
4109 instr, | 4122 instr, |
4110 CALL_AS_METHOD, | 4123 CALL_AS_METHOD, |
4111 EDI_CONTAINS_TARGET); | 4124 EDI_CONTAINS_TARGET); |
4112 } | 4125 } |
4113 } | 4126 } |
4114 | 4127 |
4115 | 4128 |
4116 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 4129 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
4117 ASSERT(ToRegister(instr->context()).is(esi)); | 4130 ASSERT(ToRegister(instr->context()).is(esi)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4157 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; | 4170 RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; |
4158 Handle<Code> ic = | 4171 Handle<Code> ic = |
4159 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 4172 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
4160 __ mov(ecx, instr->name()); | 4173 __ mov(ecx, instr->name()); |
4161 CallCode(ic, mode, instr); | 4174 CallCode(ic, mode, instr); |
4162 } | 4175 } |
4163 | 4176 |
4164 | 4177 |
4165 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 4178 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
4166 ASSERT(ToRegister(instr->result()).is(eax)); | 4179 ASSERT(ToRegister(instr->result()).is(eax)); |
4167 CallKnownFunction(instr->target(), | 4180 CallKnownFunction(instr->hydrogen()->target(), |
| 4181 instr->hydrogen()->formal_parameter_count(), |
4168 instr->arity(), | 4182 instr->arity(), |
4169 instr, | 4183 instr, |
4170 CALL_AS_FUNCTION, | 4184 CALL_AS_FUNCTION, |
4171 EDI_UNINITIALIZED); | 4185 EDI_UNINITIALIZED); |
4172 } | 4186 } |
4173 | 4187 |
4174 | 4188 |
4175 void LCodeGen::DoCallNew(LCallNew* instr) { | 4189 void LCodeGen::DoCallNew(LCallNew* instr) { |
4176 ASSERT(ToRegister(instr->context()).is(esi)); | 4190 ASSERT(ToRegister(instr->context()).is(esi)); |
4177 ASSERT(ToRegister(instr->constructor()).is(edi)); | 4191 ASSERT(ToRegister(instr->constructor()).is(edi)); |
(...skipping 1705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5883 private: | 5897 private: |
5884 LAllocateObject* instr_; | 5898 LAllocateObject* instr_; |
5885 }; | 5899 }; |
5886 | 5900 |
5887 DeferredAllocateObject* deferred = | 5901 DeferredAllocateObject* deferred = |
5888 new(zone()) DeferredAllocateObject(this, instr); | 5902 new(zone()) DeferredAllocateObject(this, instr); |
5889 | 5903 |
5890 Register result = ToRegister(instr->result()); | 5904 Register result = ToRegister(instr->result()); |
5891 Register scratch = ToRegister(instr->temp()); | 5905 Register scratch = ToRegister(instr->temp()); |
5892 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5906 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); |
5893 Handle<Map> initial_map(constructor->initial_map()); | 5907 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
5894 int instance_size = initial_map->instance_size(); | 5908 int instance_size = initial_map->instance_size(); |
5895 ASSERT(initial_map->pre_allocated_property_fields() + | 5909 ASSERT(initial_map->pre_allocated_property_fields() + |
5896 initial_map->unused_property_fields() - | 5910 initial_map->unused_property_fields() - |
5897 initial_map->inobject_properties() == 0); | 5911 initial_map->inobject_properties() == 0); |
5898 | 5912 |
5899 // Allocate memory for the object. The initial map might change when | |
5900 // the constructor's prototype changes, but instance size and property | |
5901 // counts remain unchanged (if slack tracking finished). | |
5902 ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); | |
5903 __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(), | 5913 __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(), |
5904 TAG_OBJECT); | 5914 TAG_OBJECT); |
5905 | 5915 |
5906 __ bind(deferred->exit()); | 5916 __ bind(deferred->exit()); |
5907 if (FLAG_debug_code) { | 5917 if (FLAG_debug_code) { |
5908 Label is_in_new_space; | 5918 Label is_in_new_space; |
5909 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); | 5919 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); |
5910 __ Abort("Allocated object is not in new-space"); | 5920 __ Abort("Allocated object is not in new-space"); |
5911 __ bind(&is_in_new_space); | 5921 __ bind(&is_in_new_space); |
5912 } | 5922 } |
(...skipping 30 matching lines...) Expand all Loading... |
5943 for (int i = 0; i < initial_map->inobject_properties(); i++) { | 5953 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
5944 int property_offset = JSObject::kHeaderSize + i * kPointerSize; | 5954 int property_offset = JSObject::kHeaderSize + i * kPointerSize; |
5945 __ mov(FieldOperand(result, property_offset), scratch); | 5955 __ mov(FieldOperand(result, property_offset), scratch); |
5946 } | 5956 } |
5947 } | 5957 } |
5948 } | 5958 } |
5949 | 5959 |
5950 | 5960 |
5951 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { | 5961 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { |
5952 Register result = ToRegister(instr->result()); | 5962 Register result = ToRegister(instr->result()); |
5953 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5963 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
5954 Handle<Map> initial_map(constructor->initial_map()); | |
5955 int instance_size = initial_map->instance_size(); | 5964 int instance_size = initial_map->instance_size(); |
5956 | 5965 |
5957 // TODO(3095996): Get rid of this. For now, we need to make the | 5966 // TODO(3095996): Get rid of this. For now, we need to make the |
5958 // result register contain a valid pointer because it is already | 5967 // result register contain a valid pointer because it is already |
5959 // contained in the register pointer map. | 5968 // contained in the register pointer map. |
5960 __ Set(result, Immediate(0)); | 5969 __ Set(result, Immediate(0)); |
5961 | 5970 |
5962 PushSafepointRegistersScope scope(this); | 5971 PushSafepointRegistersScope scope(this); |
5963 __ push(Immediate(Smi::FromInt(instance_size))); | 5972 __ push(Immediate(Smi::FromInt(instance_size))); |
5964 CallRuntimeFromDeferred( | 5973 CallRuntimeFromDeferred( |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6023 } else { | 6032 } else { |
6024 CallRuntimeFromDeferred( | 6033 CallRuntimeFromDeferred( |
6025 Runtime::kAllocateInNewSpace, 1, instr, instr->context()); | 6034 Runtime::kAllocateInNewSpace, 1, instr, instr->context()); |
6026 } | 6035 } |
6027 __ StoreToSafepointRegisterSlot(result, eax); | 6036 __ StoreToSafepointRegisterSlot(result, eax); |
6028 } | 6037 } |
6029 | 6038 |
6030 | 6039 |
6031 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 6040 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
6032 ASSERT(ToRegister(instr->context()).is(esi)); | 6041 ASSERT(ToRegister(instr->context()).is(esi)); |
6033 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 6042 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
6034 ElementsKind boilerplate_elements_kind = | 6043 ElementsKind boilerplate_elements_kind = |
6035 instr->hydrogen()->boilerplate_elements_kind(); | 6044 instr->hydrogen()->boilerplate_elements_kind(); |
6036 AllocationSiteMode allocation_site_mode = | 6045 AllocationSiteMode allocation_site_mode = |
6037 instr->hydrogen()->allocation_site_mode(); | 6046 instr->hydrogen()->allocation_site_mode(); |
6038 | 6047 |
6039 // Deopt if the array literal boilerplate ElementsKind is of a type different | 6048 // Deopt if the array literal boilerplate ElementsKind is of a type different |
6040 // than the expected one. The check isn't necessary if the boilerplate has | 6049 // than the expected one. The check isn't necessary if the boilerplate has |
6041 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 6050 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
6042 if (CanTransitionToMoreGeneralFastElementsKind( | 6051 if (CanTransitionToMoreGeneralFastElementsKind( |
6043 boilerplate_elements_kind, true)) { | 6052 boilerplate_elements_kind, true)) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6084 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 6093 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
6085 : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 6094 : FastCloneShallowArrayStub::CLONE_ELEMENTS; |
6086 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 6095 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); |
6087 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 6096 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
6088 } | 6097 } |
6089 } | 6098 } |
6090 | 6099 |
6091 | 6100 |
6092 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 6101 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
6093 ASSERT(ToRegister(instr->context()).is(esi)); | 6102 ASSERT(ToRegister(instr->context()).is(esi)); |
6094 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 6103 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
6095 Handle<FixedArray> constant_properties = | 6104 Handle<FixedArray> constant_properties = |
6096 instr->hydrogen()->constant_properties(); | 6105 instr->hydrogen()->constant_properties(); |
6097 | 6106 |
6098 int flags = instr->hydrogen()->fast_elements() | 6107 int flags = instr->hydrogen()->fast_elements() |
6099 ? ObjectLiteral::kFastElements | 6108 ? ObjectLiteral::kFastElements |
6100 : ObjectLiteral::kNoFlags; | 6109 : ObjectLiteral::kNoFlags; |
6101 flags |= instr->hydrogen()->has_function() | 6110 flags |= instr->hydrogen()->has_function() |
6102 ? ObjectLiteral::kHasFunction | 6111 ? ObjectLiteral::kHasFunction |
6103 : ObjectLiteral::kNoFlags; | 6112 : ObjectLiteral::kNoFlags; |
6104 | 6113 |
6105 // Set up the parameters to the stub/runtime call and pick the right | 6114 // Set up the parameters to the stub/runtime call and pick the right |
6106 // runtime function or stub to call. | 6115 // runtime function or stub to call. |
6107 int properties_count = constant_properties->length() / 2; | 6116 int properties_count = instr->hydrogen()->constant_properties_length() / 2; |
6108 if (instr->hydrogen()->depth() > 1) { | 6117 if (instr->hydrogen()->depth() > 1) { |
6109 __ PushHeapObject(literals); | 6118 __ PushHeapObject(literals); |
6110 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 6119 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); |
6111 __ push(Immediate(constant_properties)); | 6120 __ push(Immediate(constant_properties)); |
6112 __ push(Immediate(Smi::FromInt(flags))); | 6121 __ push(Immediate(Smi::FromInt(flags))); |
6113 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); | 6122 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); |
6114 } else if (flags != ObjectLiteral::kFastElements || | 6123 } else if (flags != ObjectLiteral::kFastElements || |
6115 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 6124 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
6116 __ PushHeapObject(literals); | 6125 __ PushHeapObject(literals); |
6117 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); | 6126 __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6185 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); | 6194 __ mov(edx, FieldOperand(ebx, size - kPointerSize)); |
6186 __ mov(FieldOperand(eax, size - kPointerSize), edx); | 6195 __ mov(FieldOperand(eax, size - kPointerSize), edx); |
6187 } | 6196 } |
6188 } | 6197 } |
6189 | 6198 |
6190 | 6199 |
6191 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 6200 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
6192 ASSERT(ToRegister(instr->context()).is(esi)); | 6201 ASSERT(ToRegister(instr->context()).is(esi)); |
6193 // Use the fast case closure allocation code that allocates in new | 6202 // Use the fast case closure allocation code that allocates in new |
6194 // space for nested functions that don't need literals cloning. | 6203 // space for nested functions that don't need literals cloning. |
6195 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | |
6196 bool pretenure = instr->hydrogen()->pretenure(); | 6204 bool pretenure = instr->hydrogen()->pretenure(); |
6197 if (!pretenure && shared_info->num_literals() == 0) { | 6205 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
6198 FastNewClosureStub stub(shared_info->language_mode(), | 6206 FastNewClosureStub stub(instr->hydrogen()->language_mode(), |
6199 shared_info->is_generator()); | 6207 instr->hydrogen()->is_generator()); |
6200 __ push(Immediate(shared_info)); | 6208 __ push(Immediate(instr->hydrogen()->shared_info())); |
6201 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 6209 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
6202 } else { | 6210 } else { |
6203 __ push(esi); | 6211 __ push(esi); |
6204 __ push(Immediate(shared_info)); | 6212 __ push(Immediate(instr->hydrogen()->shared_info())); |
6205 __ push(Immediate(pretenure | 6213 __ push(Immediate(pretenure ? factory()->true_value() |
6206 ? factory()->true_value() | 6214 : factory()->false_value())); |
6207 : factory()->false_value())); | |
6208 CallRuntime(Runtime::kNewClosure, 3, instr); | 6215 CallRuntime(Runtime::kNewClosure, 3, instr); |
6209 } | 6216 } |
6210 } | 6217 } |
6211 | 6218 |
6212 | 6219 |
6213 void LCodeGen::DoTypeof(LTypeof* instr) { | 6220 void LCodeGen::DoTypeof(LTypeof* instr) { |
6214 LOperand* input = instr->value(); | 6221 LOperand* input = instr->value(); |
6215 EmitPushTaggedOperand(input); | 6222 EmitPushTaggedOperand(input); |
6216 CallRuntime(Runtime::kTypeof, 1, instr); | 6223 CallRuntime(Runtime::kTypeof, 1, instr); |
6217 } | 6224 } |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6565 FixedArray::kHeaderSize - kPointerSize)); | 6572 FixedArray::kHeaderSize - kPointerSize)); |
6566 __ bind(&done); | 6573 __ bind(&done); |
6567 } | 6574 } |
6568 | 6575 |
6569 | 6576 |
6570 #undef __ | 6577 #undef __ |
6571 | 6578 |
6572 } } // namespace v8::internal | 6579 } } // namespace v8::internal |
6573 | 6580 |
6574 #endif // V8_TARGET_ARCH_IA32 | 6581 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |