| 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 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 // values on the stack that represent the arguments. This needs to be | 588 // values on the stack that represent the arguments. This needs to be |
| 589 // kept in sync with the LArgumentsElements implementation. | 589 // kept in sync with the LArgumentsElements implementation. |
| 590 *pushed_arguments_index = -environment->parameter_count(); | 590 *pushed_arguments_index = -environment->parameter_count(); |
| 591 *pushed_arguments_count = environment->parameter_count(); | 591 *pushed_arguments_count = environment->parameter_count(); |
| 592 | 592 |
| 593 WriteTranslation(environment->outer(), | 593 WriteTranslation(environment->outer(), |
| 594 translation, | 594 translation, |
| 595 pushed_arguments_index, | 595 pushed_arguments_index, |
| 596 pushed_arguments_count); | 596 pushed_arguments_count); |
| 597 bool has_closure_id = !info()->closure().is_null() && | 597 bool has_closure_id = !info()->closure().is_null() && |
| 598 *info()->closure() != *environment->closure(); | 598 !info()->closure().is_identical_to(environment->closure()); |
| 599 int closure_id = has_closure_id | 599 int closure_id = has_closure_id |
| 600 ? DefineDeoptimizationLiteral(environment->closure()) | 600 ? DefineDeoptimizationLiteral(environment->closure()) |
| 601 : Translation::kSelfLiteralId; | 601 : Translation::kSelfLiteralId; |
| 602 | 602 |
| 603 switch (environment->frame_type()) { | 603 switch (environment->frame_type()) { |
| 604 case JS_FUNCTION: | 604 case JS_FUNCTION: |
| 605 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 605 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
| 606 break; | 606 break; |
| 607 case JS_CONSTRUCT: | 607 case JS_CONSTRUCT: |
| 608 translation->BeginConstructStubFrame(closure_id, translation_size); | 608 translation->BeginConstructStubFrame(closure_id, translation_size); |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 904 Handle<DeoptimizationInputData> data = | 904 Handle<DeoptimizationInputData> data = |
| 905 factory()->NewDeoptimizationInputData(length, TENURED); | 905 factory()->NewDeoptimizationInputData(length, TENURED); |
| 906 | 906 |
| 907 Handle<ByteArray> translations = | 907 Handle<ByteArray> translations = |
| 908 translations_.CreateByteArray(isolate()->factory()); | 908 translations_.CreateByteArray(isolate()->factory()); |
| 909 data->SetTranslationByteArray(*translations); | 909 data->SetTranslationByteArray(*translations); |
| 910 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 910 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
| 911 | 911 |
| 912 Handle<FixedArray> literals = | 912 Handle<FixedArray> literals = |
| 913 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 913 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
| 914 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 914 { ALLOW_HANDLE_DEREF("copying a ZoneList of handles into a FixedArray"); |
| 915 literals->set(i, *deoptimization_literals_[i]); | 915 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 916 literals->set(i, *deoptimization_literals_[i]); |
| 917 } |
| 918 data->SetLiteralArray(*literals); |
| 916 } | 919 } |
| 917 data->SetLiteralArray(*literals); | |
| 918 | 920 |
| 919 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 921 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
| 920 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 922 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
| 921 | 923 |
| 922 // Populate the deoptimization entries. | 924 // Populate the deoptimization entries. |
| 923 for (int i = 0; i < length; i++) { | 925 for (int i = 0; i < length; i++) { |
| 924 LEnvironment* env = deoptimizations_[i]; | 926 LEnvironment* env = deoptimizations_[i]; |
| 925 data->SetAstId(i, env->ast_id()); | 927 data->SetAstId(i, env->ast_id()); |
| 926 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 928 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
| 927 data->SetArgumentsStackHeight(i, | 929 data->SetArgumentsStackHeight(i, |
| (...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 void LCodeGen::DoConstantD(LConstantD* instr) { | 1896 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 1895 ASSERT(instr->result()->IsDoubleRegister()); | 1897 ASSERT(instr->result()->IsDoubleRegister()); |
| 1896 DwVfpRegister result = ToDoubleRegister(instr->result()); | 1898 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 1897 double v = instr->value(); | 1899 double v = instr->value(); |
| 1898 __ Vmov(result, v, scratch0()); | 1900 __ Vmov(result, v, scratch0()); |
| 1899 } | 1901 } |
| 1900 | 1902 |
| 1901 | 1903 |
| 1902 void LCodeGen::DoConstantT(LConstantT* instr) { | 1904 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1903 Handle<Object> value = instr->value(); | 1905 Handle<Object> value = instr->value(); |
| 1906 ALLOW_HANDLE_DEREF("smi check"); |
| 1904 if (value->IsSmi()) { | 1907 if (value->IsSmi()) { |
| 1905 __ mov(ToRegister(instr->result()), Operand(value)); | 1908 __ mov(ToRegister(instr->result()), Operand(value)); |
| 1906 } else { | 1909 } else { |
| 1907 __ LoadHeapObject(ToRegister(instr->result()), | 1910 __ LoadHeapObject(ToRegister(instr->result()), |
| 1908 Handle<HeapObject>::cast(value)); | 1911 Handle<HeapObject>::cast(value)); |
| 1909 } | 1912 } |
| 1910 } | 1913 } |
| 1911 | 1914 |
| 1912 | 1915 |
| 1913 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { | 1916 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { |
| (...skipping 1784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3698 | 3701 |
| 3699 | 3702 |
| 3700 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 3703 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
| 3701 Register global = ToRegister(instr->global_object()); | 3704 Register global = ToRegister(instr->global_object()); |
| 3702 Register result = ToRegister(instr->result()); | 3705 Register result = ToRegister(instr->result()); |
| 3703 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 3706 __ ldr(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
| 3704 } | 3707 } |
| 3705 | 3708 |
| 3706 | 3709 |
| 3707 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3710 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
| 3711 int formal_parameter_count, |
| 3708 int arity, | 3712 int arity, |
| 3709 LInstruction* instr, | 3713 LInstruction* instr, |
| 3710 CallKind call_kind, | 3714 CallKind call_kind, |
| 3711 R1State r1_state) { | 3715 R1State r1_state) { |
| 3712 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || | 3716 bool dont_adapt_arguments = |
| 3713 function->shared()->formal_parameter_count() == arity; | 3717 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3718 bool can_invoke_directly = |
| 3719 dont_adapt_arguments || formal_parameter_count == arity; |
| 3714 | 3720 |
| 3715 LPointerMap* pointers = instr->pointer_map(); | 3721 LPointerMap* pointers = instr->pointer_map(); |
| 3716 RecordPosition(pointers->position()); | 3722 RecordPosition(pointers->position()); |
| 3717 | 3723 |
| 3718 if (can_invoke_directly) { | 3724 if (can_invoke_directly) { |
| 3719 if (r1_state == R1_UNINITIALIZED) { | 3725 if (r1_state == R1_UNINITIALIZED) { |
| 3720 __ LoadHeapObject(r1, function); | 3726 __ LoadHeapObject(r1, function); |
| 3721 } | 3727 } |
| 3722 | 3728 |
| 3723 // Change context. | 3729 // Change context. |
| 3724 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 3730 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 3725 | 3731 |
| 3726 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | 3732 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
| 3727 // is available to write to at this point. | 3733 // is available to write to at this point. |
| 3728 if (!function->NeedsArgumentsAdaption()) { | 3734 if (dont_adapt_arguments) { |
| 3729 __ mov(r0, Operand(arity)); | 3735 __ mov(r0, Operand(arity)); |
| 3730 } | 3736 } |
| 3731 | 3737 |
| 3732 // Invoke function. | 3738 // Invoke function. |
| 3733 __ SetCallKind(r5, call_kind); | 3739 __ SetCallKind(r5, call_kind); |
| 3734 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); | 3740 __ ldr(ip, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); |
| 3735 __ Call(ip); | 3741 __ Call(ip); |
| 3736 | 3742 |
| 3737 // Set up deoptimization. | 3743 // Set up deoptimization. |
| 3738 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 3744 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 3739 } else { | 3745 } else { |
| 3740 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3746 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 3741 ParameterCount count(arity); | 3747 ParameterCount count(arity); |
| 3742 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); | 3748 ParameterCount expected(formal_parameter_count); |
| 3749 __ InvokeFunction( |
| 3750 function, expected, count, CALL_FUNCTION, generator, call_kind); |
| 3743 } | 3751 } |
| 3744 | 3752 |
| 3745 // Restore context. | 3753 // Restore context. |
| 3746 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3754 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3747 } | 3755 } |
| 3748 | 3756 |
| 3749 | 3757 |
| 3750 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3758 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
| 3751 ASSERT(ToRegister(instr->result()).is(r0)); | 3759 ASSERT(ToRegister(instr->result()).is(r0)); |
| 3752 CallKnownFunction(instr->function(), | 3760 CallKnownFunction(instr->hydrogen()->function(), |
| 3761 instr->hydrogen()->formal_parameter_count(), |
| 3753 instr->arity(), | 3762 instr->arity(), |
| 3754 instr, | 3763 instr, |
| 3755 CALL_AS_METHOD, | 3764 CALL_AS_METHOD, |
| 3756 R1_UNINITIALIZED); | 3765 R1_UNINITIALIZED); |
| 3757 } | 3766 } |
| 3758 | 3767 |
| 3759 | 3768 |
| 3760 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3769 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
| 3761 Register input = ToRegister(instr->value()); | 3770 Register input = ToRegister(instr->value()); |
| 3762 Register result = ToRegister(instr->result()); | 3771 Register result = ToRegister(instr->result()); |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4114 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 4123 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
| 4115 TranscendentalCacheStub::UNTAGGED); | 4124 TranscendentalCacheStub::UNTAGGED); |
| 4116 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4125 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4117 } | 4126 } |
| 4118 | 4127 |
| 4119 | 4128 |
| 4120 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 4129 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 4121 ASSERT(ToRegister(instr->function()).is(r1)); | 4130 ASSERT(ToRegister(instr->function()).is(r1)); |
| 4122 ASSERT(instr->HasPointerMap()); | 4131 ASSERT(instr->HasPointerMap()); |
| 4123 | 4132 |
| 4124 if (instr->known_function().is_null()) { | 4133 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 4134 if (known_function.is_null()) { |
| 4125 LPointerMap* pointers = instr->pointer_map(); | 4135 LPointerMap* pointers = instr->pointer_map(); |
| 4126 RecordPosition(pointers->position()); | 4136 RecordPosition(pointers->position()); |
| 4127 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 4137 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 4128 ParameterCount count(instr->arity()); | 4138 ParameterCount count(instr->arity()); |
| 4129 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 4139 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
| 4130 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4140 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4131 } else { | 4141 } else { |
| 4132 CallKnownFunction(instr->known_function(), | 4142 CallKnownFunction(known_function, |
| 4143 instr->hydrogen()->formal_parameter_count(), |
| 4133 instr->arity(), | 4144 instr->arity(), |
| 4134 instr, | 4145 instr, |
| 4135 CALL_AS_METHOD, | 4146 CALL_AS_METHOD, |
| 4136 R1_CONTAINS_TARGET); | 4147 R1_CONTAINS_TARGET); |
| 4137 } | 4148 } |
| 4138 } | 4149 } |
| 4139 | 4150 |
| 4140 | 4151 |
| 4141 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 4152 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
| 4142 ASSERT(ToRegister(instr->result()).is(r0)); | 4153 ASSERT(ToRegister(instr->result()).is(r0)); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4182 Handle<Code> ic = | 4193 Handle<Code> ic = |
| 4183 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 4194 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
| 4184 __ mov(r2, Operand(instr->name())); | 4195 __ mov(r2, Operand(instr->name())); |
| 4185 CallCode(ic, mode, instr, NEVER_INLINE_TARGET_ADDRESS); | 4196 CallCode(ic, mode, instr, NEVER_INLINE_TARGET_ADDRESS); |
| 4186 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4197 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4187 } | 4198 } |
| 4188 | 4199 |
| 4189 | 4200 |
| 4190 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 4201 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
| 4191 ASSERT(ToRegister(instr->result()).is(r0)); | 4202 ASSERT(ToRegister(instr->result()).is(r0)); |
| 4192 CallKnownFunction(instr->target(), | 4203 CallKnownFunction(instr->hydrogen()->target(), |
| 4204 instr->hydrogen()->formal_parameter_count(), |
| 4193 instr->arity(), | 4205 instr->arity(), |
| 4194 instr, | 4206 instr, |
| 4195 CALL_AS_FUNCTION, | 4207 CALL_AS_FUNCTION, |
| 4196 R1_UNINITIALIZED); | 4208 R1_UNINITIALIZED); |
| 4197 } | 4209 } |
| 4198 | 4210 |
| 4199 | 4211 |
| 4200 void LCodeGen::DoCallNew(LCallNew* instr) { | 4212 void LCodeGen::DoCallNew(LCallNew* instr) { |
| 4201 ASSERT(ToRegister(instr->constructor()).is(r1)); | 4213 ASSERT(ToRegister(instr->constructor()).is(r1)); |
| 4202 ASSERT(ToRegister(instr->result()).is(r0)); | 4214 ASSERT(ToRegister(instr->result()).is(r0)); |
| (...skipping 999 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5202 __ cmp(scratch, Operand(tag)); | 5214 __ cmp(scratch, Operand(tag)); |
| 5203 DeoptimizeIf(ne, instr->environment()); | 5215 DeoptimizeIf(ne, instr->environment()); |
| 5204 } | 5216 } |
| 5205 } | 5217 } |
| 5206 } | 5218 } |
| 5207 | 5219 |
| 5208 | 5220 |
| 5209 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 5221 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
| 5210 Register reg = ToRegister(instr->value()); | 5222 Register reg = ToRegister(instr->value()); |
| 5211 Handle<JSFunction> target = instr->hydrogen()->target(); | 5223 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 5224 ALLOW_HANDLE_DEREF("smi check"); |
| 5212 if (isolate()->heap()->InNewSpace(*target)) { | 5225 if (isolate()->heap()->InNewSpace(*target)) { |
| 5213 Register reg = ToRegister(instr->value()); | 5226 Register reg = ToRegister(instr->value()); |
| 5214 Handle<JSGlobalPropertyCell> cell = | 5227 Handle<JSGlobalPropertyCell> cell = |
| 5215 isolate()->factory()->NewJSGlobalPropertyCell(target); | 5228 isolate()->factory()->NewJSGlobalPropertyCell(target); |
| 5216 __ mov(ip, Operand(Handle<Object>(cell))); | 5229 __ mov(ip, Operand(Handle<Object>(cell))); |
| 5217 __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); | 5230 __ ldr(ip, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); |
| 5218 __ cmp(reg, ip); | 5231 __ cmp(reg, ip); |
| 5219 } else { | 5232 } else { |
| 5220 __ cmp(reg, Operand(target)); | 5233 __ cmp(reg, Operand(target)); |
| 5221 } | 5234 } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5343 LAllocateObject* instr_; | 5356 LAllocateObject* instr_; |
| 5344 }; | 5357 }; |
| 5345 | 5358 |
| 5346 DeferredAllocateObject* deferred = | 5359 DeferredAllocateObject* deferred = |
| 5347 new(zone()) DeferredAllocateObject(this, instr); | 5360 new(zone()) DeferredAllocateObject(this, instr); |
| 5348 | 5361 |
| 5349 Register result = ToRegister(instr->result()); | 5362 Register result = ToRegister(instr->result()); |
| 5350 Register scratch = ToRegister(instr->temp()); | 5363 Register scratch = ToRegister(instr->temp()); |
| 5351 Register scratch2 = ToRegister(instr->temp2()); | 5364 Register scratch2 = ToRegister(instr->temp2()); |
| 5352 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5365 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); |
| 5353 Handle<Map> initial_map(constructor->initial_map()); | 5366 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
| 5354 int instance_size = initial_map->instance_size(); | 5367 int instance_size = initial_map->instance_size(); |
| 5355 ASSERT(initial_map->pre_allocated_property_fields() + | 5368 ASSERT(initial_map->pre_allocated_property_fields() + |
| 5356 initial_map->unused_property_fields() - | 5369 initial_map->unused_property_fields() - |
| 5357 initial_map->inobject_properties() == 0); | 5370 initial_map->inobject_properties() == 0); |
| 5358 | 5371 |
| 5359 // Allocate memory for the object. The initial map might change when | |
| 5360 // the constructor's prototype changes, but instance size and property | |
| 5361 // counts remain unchanged (if slack tracking finished). | |
| 5362 ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); | |
| 5363 __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(), | 5372 __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(), |
| 5364 TAG_OBJECT); | 5373 TAG_OBJECT); |
| 5365 | 5374 |
| 5366 __ bind(deferred->exit()); | 5375 __ bind(deferred->exit()); |
| 5367 if (FLAG_debug_code) { | 5376 if (FLAG_debug_code) { |
| 5368 Label is_in_new_space; | 5377 Label is_in_new_space; |
| 5369 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); | 5378 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); |
| 5370 __ Abort("Allocated object is not in new-space"); | 5379 __ Abort("Allocated object is not in new-space"); |
| 5371 __ bind(&is_in_new_space); | 5380 __ bind(&is_in_new_space); |
| 5372 } | 5381 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5387 for (int i = 0; i < initial_map->inobject_properties(); i++) { | 5396 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
| 5388 int property_offset = JSObject::kHeaderSize + i * kPointerSize; | 5397 int property_offset = JSObject::kHeaderSize + i * kPointerSize; |
| 5389 __ str(scratch, FieldMemOperand(result, property_offset)); | 5398 __ str(scratch, FieldMemOperand(result, property_offset)); |
| 5390 } | 5399 } |
| 5391 } | 5400 } |
| 5392 } | 5401 } |
| 5393 | 5402 |
| 5394 | 5403 |
| 5395 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { | 5404 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { |
| 5396 Register result = ToRegister(instr->result()); | 5405 Register result = ToRegister(instr->result()); |
| 5397 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5406 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
| 5398 Handle<Map> initial_map(constructor->initial_map()); | |
| 5399 int instance_size = initial_map->instance_size(); | 5407 int instance_size = initial_map->instance_size(); |
| 5400 | 5408 |
| 5401 // TODO(3095996): Get rid of this. For now, we need to make the | 5409 // TODO(3095996): Get rid of this. For now, we need to make the |
| 5402 // result register contain a valid pointer because it is already | 5410 // result register contain a valid pointer because it is already |
| 5403 // contained in the register pointer map. | 5411 // contained in the register pointer map. |
| 5404 __ mov(result, Operand::Zero()); | 5412 __ mov(result, Operand::Zero()); |
| 5405 | 5413 |
| 5406 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 5414 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
| 5407 __ mov(r0, Operand(Smi::FromInt(instance_size))); | 5415 __ mov(r0, Operand(Smi::FromInt(instance_size))); |
| 5408 __ push(r0); | 5416 __ push(r0); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5471 Runtime::kAllocateInOldPointerSpace, 1, instr); | 5479 Runtime::kAllocateInOldPointerSpace, 1, instr); |
| 5472 } else { | 5480 } else { |
| 5473 CallRuntimeFromDeferred( | 5481 CallRuntimeFromDeferred( |
| 5474 Runtime::kAllocateInNewSpace, 1, instr); | 5482 Runtime::kAllocateInNewSpace, 1, instr); |
| 5475 } | 5483 } |
| 5476 __ StoreToSafepointRegisterSlot(r0, result); | 5484 __ StoreToSafepointRegisterSlot(r0, result); |
| 5477 } | 5485 } |
| 5478 | 5486 |
| 5479 | 5487 |
| 5480 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 5488 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
| 5481 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5489 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
| 5482 ElementsKind boilerplate_elements_kind = | 5490 ElementsKind boilerplate_elements_kind = |
| 5483 instr->hydrogen()->boilerplate_elements_kind(); | 5491 instr->hydrogen()->boilerplate_elements_kind(); |
| 5484 AllocationSiteMode allocation_site_mode = | 5492 AllocationSiteMode allocation_site_mode = |
| 5485 instr->hydrogen()->allocation_site_mode(); | 5493 instr->hydrogen()->allocation_site_mode(); |
| 5486 | 5494 |
| 5487 // Deopt if the array literal boilerplate ElementsKind is of a type different | 5495 // Deopt if the array literal boilerplate ElementsKind is of a type different |
| 5488 // than the expected one. The check isn't necessary if the boilerplate has | 5496 // than the expected one. The check isn't necessary if the boilerplate has |
| 5489 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 5497 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
| 5490 if (CanTransitionToMoreGeneralFastElementsKind( | 5498 if (CanTransitionToMoreGeneralFastElementsKind( |
| 5491 boilerplate_elements_kind, true)) { | 5499 boilerplate_elements_kind, true)) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5526 boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS | 5534 boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS |
| 5527 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 5535 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
| 5528 : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 5536 : FastCloneShallowArrayStub::CLONE_ELEMENTS; |
| 5529 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 5537 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); |
| 5530 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5538 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 5531 } | 5539 } |
| 5532 } | 5540 } |
| 5533 | 5541 |
| 5534 | 5542 |
| 5535 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 5543 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
| 5536 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5544 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
| 5537 Handle<FixedArray> constant_properties = | 5545 Handle<FixedArray> constant_properties = |
| 5538 instr->hydrogen()->constant_properties(); | 5546 instr->hydrogen()->constant_properties(); |
| 5539 | 5547 |
| 5540 // Set up the parameters to the stub/runtime call. | 5548 // Set up the parameters to the stub/runtime call. |
| 5541 __ LoadHeapObject(r3, literals); | 5549 __ LoadHeapObject(r3, literals); |
| 5542 __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); | 5550 __ mov(r2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| 5543 __ mov(r1, Operand(constant_properties)); | 5551 __ mov(r1, Operand(constant_properties)); |
| 5544 int flags = instr->hydrogen()->fast_elements() | 5552 int flags = instr->hydrogen()->fast_elements() |
| 5545 ? ObjectLiteral::kFastElements | 5553 ? ObjectLiteral::kFastElements |
| 5546 : ObjectLiteral::kNoFlags; | 5554 : ObjectLiteral::kNoFlags; |
| 5547 __ mov(r0, Operand(Smi::FromInt(flags))); | 5555 __ mov(r0, Operand(Smi::FromInt(flags))); |
| 5548 | 5556 |
| 5549 // Pick the right runtime function or stub to call. | 5557 // Pick the right runtime function or stub to call. |
| 5550 int properties_count = constant_properties->length() / 2; | 5558 int properties_count = instr->hydrogen()->constant_properties_length() / 2; |
| 5551 if (instr->hydrogen()->depth() > 1) { | 5559 if (instr->hydrogen()->depth() > 1) { |
| 5552 __ Push(r3, r2, r1, r0); | 5560 __ Push(r3, r2, r1, r0); |
| 5553 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); | 5561 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); |
| 5554 } else if (flags != ObjectLiteral::kFastElements || | 5562 } else if (flags != ObjectLiteral::kFastElements || |
| 5555 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 5563 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
| 5556 __ Push(r3, r2, r1, r0); | 5564 __ Push(r3, r2, r1, r0); |
| 5557 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); | 5565 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); |
| 5558 } else { | 5566 } else { |
| 5559 FastCloneShallowObjectStub stub(properties_count); | 5567 FastCloneShallowObjectStub stub(properties_count); |
| 5560 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5568 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5609 __ bind(&allocated); | 5617 __ bind(&allocated); |
| 5610 // Copy the content into the newly allocated memory. | 5618 // Copy the content into the newly allocated memory. |
| 5611 __ CopyFields(r0, r1, double_scratch0(), double_scratch0().low(), | 5619 __ CopyFields(r0, r1, double_scratch0(), double_scratch0().low(), |
| 5612 size / kPointerSize); | 5620 size / kPointerSize); |
| 5613 } | 5621 } |
| 5614 | 5622 |
| 5615 | 5623 |
| 5616 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 5624 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
| 5617 // Use the fast case closure allocation code that allocates in new | 5625 // Use the fast case closure allocation code that allocates in new |
| 5618 // space for nested functions that don't need literals cloning. | 5626 // space for nested functions that don't need literals cloning. |
| 5619 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | 5627 Handle<SharedFunctionInfo> shared_info = instr->hydrogen()->shared_info(); |
| 5620 bool pretenure = instr->hydrogen()->pretenure(); | 5628 bool pretenure = instr->hydrogen()->pretenure(); |
| 5621 if (!pretenure && shared_info->num_literals() == 0) { | 5629 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
| 5622 FastNewClosureStub stub(shared_info->language_mode(), | 5630 FastNewClosureStub stub(instr->hydrogen()->language_mode(), |
| 5623 shared_info->is_generator()); | 5631 instr->hydrogen()->is_generator()); |
| 5624 __ mov(r1, Operand(shared_info)); | 5632 __ mov(r1, Operand(shared_info)); |
| 5625 __ push(r1); | 5633 __ push(r1); |
| 5626 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5634 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 5627 } else { | 5635 } else { |
| 5628 __ mov(r2, Operand(shared_info)); | 5636 __ mov(r2, Operand(shared_info)); |
| 5629 __ mov(r1, Operand(pretenure | 5637 __ mov(r1, Operand(pretenure ? factory()->true_value() |
| 5630 ? factory()->true_value() | 5638 : factory()->false_value())); |
| 5631 : factory()->false_value())); | |
| 5632 __ Push(cp, r2, r1); | 5639 __ Push(cp, r2, r1); |
| 5633 CallRuntime(Runtime::kNewClosure, 3, instr); | 5640 CallRuntime(Runtime::kNewClosure, 3, instr); |
| 5634 } | 5641 } |
| 5635 } | 5642 } |
| 5636 | 5643 |
| 5637 | 5644 |
| 5638 void LCodeGen::DoTypeof(LTypeof* instr) { | 5645 void LCodeGen::DoTypeof(LTypeof* instr) { |
| 5639 Register input = ToRegister(instr->value()); | 5646 Register input = ToRegister(instr->value()); |
| 5640 __ push(input); | 5647 __ push(input); |
| 5641 CallRuntime(Runtime::kTypeof, 1, instr); | 5648 CallRuntime(Runtime::kTypeof, 1, instr); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5997 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6004 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 5998 __ ldr(result, FieldMemOperand(scratch, | 6005 __ ldr(result, FieldMemOperand(scratch, |
| 5999 FixedArray::kHeaderSize - kPointerSize)); | 6006 FixedArray::kHeaderSize - kPointerSize)); |
| 6000 __ bind(&done); | 6007 __ bind(&done); |
| 6001 } | 6008 } |
| 6002 | 6009 |
| 6003 | 6010 |
| 6004 #undef __ | 6011 #undef __ |
| 6005 | 6012 |
| 6006 } } // namespace v8::internal | 6013 } } // namespace v8::internal |
| OLD | NEW |