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

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: 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
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("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
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
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
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
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
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
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
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
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
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
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
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

Powered by Google App Engine
This is Rietveld 408576698