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

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

Issue 14403015: Disallow dereferencing deferred handles when generating optimized code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 8 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/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698