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 |