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