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