OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 // values on the stack that represent the arguments. This needs to be | 476 // values on the stack that represent the arguments. This needs to be |
477 // kept in sync with the LArgumentsElements implementation. | 477 // kept in sync with the LArgumentsElements implementation. |
478 *pushed_arguments_index = -environment->parameter_count(); | 478 *pushed_arguments_index = -environment->parameter_count(); |
479 *pushed_arguments_count = environment->parameter_count(); | 479 *pushed_arguments_count = environment->parameter_count(); |
480 | 480 |
481 WriteTranslation(environment->outer(), | 481 WriteTranslation(environment->outer(), |
482 translation, | 482 translation, |
483 pushed_arguments_index, | 483 pushed_arguments_index, |
484 pushed_arguments_count); | 484 pushed_arguments_count); |
485 bool has_closure_id = !info()->closure().is_null() && | 485 bool has_closure_id = !info()->closure().is_null() && |
486 *info()->closure() != *environment->closure(); | 486 !info()->closure().is_identical_to(environment->closure()); |
487 int closure_id = has_closure_id | 487 int closure_id = has_closure_id |
488 ? DefineDeoptimizationLiteral(environment->closure()) | 488 ? DefineDeoptimizationLiteral(environment->closure()) |
489 : Translation::kSelfLiteralId; | 489 : Translation::kSelfLiteralId; |
490 | 490 |
491 switch (environment->frame_type()) { | 491 switch (environment->frame_type()) { |
492 case JS_FUNCTION: | 492 case JS_FUNCTION: |
493 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 493 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
494 break; | 494 break; |
495 case JS_CONSTRUCT: | 495 case JS_CONSTRUCT: |
496 translation->BeginConstructStubFrame(closure_id, translation_size); | 496 translation->BeginConstructStubFrame(closure_id, translation_size); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
793 Handle<DeoptimizationInputData> data = | 793 Handle<DeoptimizationInputData> data = |
794 factory()->NewDeoptimizationInputData(length, TENURED); | 794 factory()->NewDeoptimizationInputData(length, TENURED); |
795 | 795 |
796 Handle<ByteArray> translations = | 796 Handle<ByteArray> translations = |
797 translations_.CreateByteArray(isolate()->factory()); | 797 translations_.CreateByteArray(isolate()->factory()); |
798 data->SetTranslationByteArray(*translations); | 798 data->SetTranslationByteArray(*translations); |
799 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 799 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
800 | 800 |
801 Handle<FixedArray> literals = | 801 Handle<FixedArray> literals = |
802 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 802 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
803 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 803 { ALLOW_HANDLE_DEREF(isolate(), |
804 literals->set(i, *deoptimization_literals_[i]); | 804 "copying a ZoneList of handles into a FixedArray"); |
| 805 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 806 literals->set(i, *deoptimization_literals_[i]); |
| 807 } |
| 808 data->SetLiteralArray(*literals); |
805 } | 809 } |
806 data->SetLiteralArray(*literals); | |
807 | 810 |
808 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 811 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
809 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 812 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
810 | 813 |
811 // Populate the deoptimization entries. | 814 // Populate the deoptimization entries. |
812 for (int i = 0; i < length; i++) { | 815 for (int i = 0; i < length; i++) { |
813 LEnvironment* env = deoptimizations_[i]; | 816 LEnvironment* env = deoptimizations_[i]; |
814 data->SetAstId(i, env->ast_id()); | 817 data->SetAstId(i, env->ast_id()); |
815 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 818 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
816 data->SetArgumentsStackHeight(i, | 819 data->SetArgumentsStackHeight(i, |
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1550 } else { | 1553 } else { |
1551 Register tmp = ToRegister(instr->temp()); | 1554 Register tmp = ToRegister(instr->temp()); |
1552 __ Set(tmp, int_val); | 1555 __ Set(tmp, int_val); |
1553 __ movq(res, tmp); | 1556 __ movq(res, tmp); |
1554 } | 1557 } |
1555 } | 1558 } |
1556 | 1559 |
1557 | 1560 |
1558 void LCodeGen::DoConstantT(LConstantT* instr) { | 1561 void LCodeGen::DoConstantT(LConstantT* instr) { |
1559 Handle<Object> value = instr->value(); | 1562 Handle<Object> value = instr->value(); |
| 1563 ALLOW_HANDLE_DEREF(isolate(), "smi check"); |
1560 if (value->IsSmi()) { | 1564 if (value->IsSmi()) { |
1561 __ Move(ToRegister(instr->result()), value); | 1565 __ Move(ToRegister(instr->result()), value); |
1562 } else { | 1566 } else { |
1563 __ LoadHeapObject(ToRegister(instr->result()), | 1567 __ LoadHeapObject(ToRegister(instr->result()), |
1564 Handle<HeapObject>::cast(value)); | 1568 Handle<HeapObject>::cast(value)); |
1565 } | 1569 } |
1566 } | 1570 } |
1567 | 1571 |
1568 | 1572 |
1569 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { | 1573 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { |
(...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3306 | 3310 |
3307 | 3311 |
3308 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 3312 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
3309 Register global = ToRegister(instr->global()); | 3313 Register global = ToRegister(instr->global()); |
3310 Register result = ToRegister(instr->result()); | 3314 Register result = ToRegister(instr->result()); |
3311 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); | 3315 __ movq(result, FieldOperand(global, GlobalObject::kGlobalReceiverOffset)); |
3312 } | 3316 } |
3313 | 3317 |
3314 | 3318 |
3315 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3319 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
| 3320 int formal_parameter_count, |
3316 int arity, | 3321 int arity, |
3317 LInstruction* instr, | 3322 LInstruction* instr, |
3318 CallKind call_kind, | 3323 CallKind call_kind, |
3319 RDIState rdi_state) { | 3324 RDIState rdi_state) { |
3320 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || | 3325 bool dont_adapt_arguments = |
3321 function->shared()->formal_parameter_count() == arity; | 3326 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3327 bool can_invoke_directly = |
| 3328 dont_adapt_arguments || formal_parameter_count == arity; |
3322 | 3329 |
3323 LPointerMap* pointers = instr->pointer_map(); | 3330 LPointerMap* pointers = instr->pointer_map(); |
3324 RecordPosition(pointers->position()); | 3331 RecordPosition(pointers->position()); |
3325 | 3332 |
3326 if (can_invoke_directly) { | 3333 if (can_invoke_directly) { |
3327 if (rdi_state == RDI_UNINITIALIZED) { | 3334 if (rdi_state == RDI_UNINITIALIZED) { |
3328 __ LoadHeapObject(rdi, function); | 3335 __ LoadHeapObject(rdi, function); |
3329 } | 3336 } |
3330 | 3337 |
3331 // Change context. | 3338 // Change context. |
3332 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 3339 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
3333 | 3340 |
3334 // Set rax to arguments count if adaption is not needed. Assumes that rax | 3341 // Set rax to arguments count if adaption is not needed. Assumes that rax |
3335 // is available to write to at this point. | 3342 // is available to write to at this point. |
3336 if (!function->NeedsArgumentsAdaption()) { | 3343 if (dont_adapt_arguments) { |
3337 __ Set(rax, arity); | 3344 __ Set(rax, arity); |
3338 } | 3345 } |
3339 | 3346 |
3340 // Invoke function. | 3347 // Invoke function. |
3341 __ SetCallKind(rcx, call_kind); | 3348 __ SetCallKind(rcx, call_kind); |
3342 if (*function == *info()->closure()) { | 3349 if (function.is_identical_to(info()->closure())) { |
3343 __ CallSelf(); | 3350 __ CallSelf(); |
3344 } else { | 3351 } else { |
3345 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); | 3352 __ call(FieldOperand(rdi, JSFunction::kCodeEntryOffset)); |
3346 } | 3353 } |
3347 | 3354 |
3348 // Set up deoptimization. | 3355 // Set up deoptimization. |
3349 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); | 3356 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT, 0); |
3350 } else { | 3357 } else { |
3351 // We need to adapt arguments. | 3358 // We need to adapt arguments. |
3352 SafepointGenerator generator( | 3359 SafepointGenerator generator( |
3353 this, pointers, Safepoint::kLazyDeopt); | 3360 this, pointers, Safepoint::kLazyDeopt); |
3354 ParameterCount count(arity); | 3361 ParameterCount count(arity); |
3355 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); | 3362 ParameterCount expected(formal_parameter_count); |
| 3363 __ InvokeFunction( |
| 3364 function, expected, count, CALL_FUNCTION, generator, call_kind); |
3356 } | 3365 } |
3357 | 3366 |
3358 // Restore context. | 3367 // Restore context. |
3359 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3368 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
3360 } | 3369 } |
3361 | 3370 |
3362 | 3371 |
3363 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3372 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
3364 ASSERT(ToRegister(instr->result()).is(rax)); | 3373 ASSERT(ToRegister(instr->result()).is(rax)); |
3365 CallKnownFunction(instr->function(), | 3374 CallKnownFunction(instr->hydrogen()->function(), |
| 3375 instr->hydrogen()->formal_parameter_count(), |
3366 instr->arity(), | 3376 instr->arity(), |
3367 instr, | 3377 instr, |
3368 CALL_AS_METHOD, | 3378 CALL_AS_METHOD, |
3369 RDI_UNINITIALIZED); | 3379 RDI_UNINITIALIZED); |
3370 } | 3380 } |
3371 | 3381 |
3372 | 3382 |
3373 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3383 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3374 Register input_reg = ToRegister(instr->value()); | 3384 Register input_reg = ToRegister(instr->value()); |
3375 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 3385 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3795 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 3805 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
3796 TranscendentalCacheStub::UNTAGGED); | 3806 TranscendentalCacheStub::UNTAGGED); |
3797 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3807 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
3798 } | 3808 } |
3799 | 3809 |
3800 | 3810 |
3801 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3811 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
3802 ASSERT(ToRegister(instr->function()).is(rdi)); | 3812 ASSERT(ToRegister(instr->function()).is(rdi)); |
3803 ASSERT(instr->HasPointerMap()); | 3813 ASSERT(instr->HasPointerMap()); |
3804 | 3814 |
3805 if (instr->known_function().is_null()) { | 3815 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 3816 if (known_function.is_null()) { |
3806 LPointerMap* pointers = instr->pointer_map(); | 3817 LPointerMap* pointers = instr->pointer_map(); |
3807 RecordPosition(pointers->position()); | 3818 RecordPosition(pointers->position()); |
3808 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3819 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3809 ParameterCount count(instr->arity()); | 3820 ParameterCount count(instr->arity()); |
3810 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 3821 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
3811 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3822 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
3812 } else { | 3823 } else { |
3813 CallKnownFunction(instr->known_function(), | 3824 CallKnownFunction(known_function, |
| 3825 instr->hydrogen()->formal_parameter_count(), |
3814 instr->arity(), | 3826 instr->arity(), |
3815 instr, | 3827 instr, |
3816 CALL_AS_METHOD, | 3828 CALL_AS_METHOD, |
3817 RDI_CONTAINS_TARGET); | 3829 RDI_CONTAINS_TARGET); |
3818 } | 3830 } |
3819 } | 3831 } |
3820 | 3832 |
3821 | 3833 |
3822 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 3834 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
3823 ASSERT(ToRegister(instr->key()).is(rcx)); | 3835 ASSERT(ToRegister(instr->key()).is(rcx)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3862 Handle<Code> ic = | 3874 Handle<Code> ic = |
3863 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3875 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
3864 __ Move(rcx, instr->name()); | 3876 __ Move(rcx, instr->name()); |
3865 CallCode(ic, mode, instr); | 3877 CallCode(ic, mode, instr); |
3866 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3878 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
3867 } | 3879 } |
3868 | 3880 |
3869 | 3881 |
3870 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3882 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3871 ASSERT(ToRegister(instr->result()).is(rax)); | 3883 ASSERT(ToRegister(instr->result()).is(rax)); |
3872 CallKnownFunction(instr->target(), | 3884 CallKnownFunction(instr->hydrogen()->target(), |
| 3885 instr->hydrogen()->formal_parameter_count(), |
3873 instr->arity(), | 3886 instr->arity(), |
3874 instr, | 3887 instr, |
3875 CALL_AS_FUNCTION, | 3888 CALL_AS_FUNCTION, |
3876 RDI_UNINITIALIZED); | 3889 RDI_UNINITIALIZED); |
3877 } | 3890 } |
3878 | 3891 |
3879 | 3892 |
3880 void LCodeGen::DoCallNew(LCallNew* instr) { | 3893 void LCodeGen::DoCallNew(LCallNew* instr) { |
3881 ASSERT(ToRegister(instr->constructor()).is(rdi)); | 3894 ASSERT(ToRegister(instr->constructor()).is(rdi)); |
3882 ASSERT(ToRegister(instr->result()).is(rax)); | 3895 ASSERT(ToRegister(instr->result()).is(rax)); |
(...skipping 980 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4863 __ cmpb(kScratchRegister, Immediate(tag)); | 4876 __ cmpb(kScratchRegister, Immediate(tag)); |
4864 DeoptimizeIf(not_equal, instr->environment()); | 4877 DeoptimizeIf(not_equal, instr->environment()); |
4865 } | 4878 } |
4866 } | 4879 } |
4867 } | 4880 } |
4868 | 4881 |
4869 | 4882 |
4870 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 4883 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
4871 Register reg = ToRegister(instr->value()); | 4884 Register reg = ToRegister(instr->value()); |
4872 Handle<JSFunction> target = instr->hydrogen()->target(); | 4885 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 4886 ALLOW_HANDLE_DEREF(isolate(), "using raw address"); |
4873 if (isolate()->heap()->InNewSpace(*target)) { | 4887 if (isolate()->heap()->InNewSpace(*target)) { |
4874 Handle<JSGlobalPropertyCell> cell = | 4888 Handle<JSGlobalPropertyCell> cell = |
4875 isolate()->factory()->NewJSGlobalPropertyCell(target); | 4889 isolate()->factory()->NewJSGlobalPropertyCell(target); |
4876 __ movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL); | 4890 __ movq(kScratchRegister, cell, RelocInfo::GLOBAL_PROPERTY_CELL); |
4877 __ cmpq(reg, Operand(kScratchRegister, 0)); | 4891 __ cmpq(reg, Operand(kScratchRegister, 0)); |
4878 } else { | 4892 } else { |
4879 __ Cmp(reg, target); | 4893 __ Cmp(reg, target); |
4880 } | 4894 } |
4881 DeoptimizeIf(not_equal, instr->environment()); | 4895 DeoptimizeIf(not_equal, instr->environment()); |
4882 } | 4896 } |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4991 private: | 5005 private: |
4992 LAllocateObject* instr_; | 5006 LAllocateObject* instr_; |
4993 }; | 5007 }; |
4994 | 5008 |
4995 DeferredAllocateObject* deferred = | 5009 DeferredAllocateObject* deferred = |
4996 new(zone()) DeferredAllocateObject(this, instr); | 5010 new(zone()) DeferredAllocateObject(this, instr); |
4997 | 5011 |
4998 Register result = ToRegister(instr->result()); | 5012 Register result = ToRegister(instr->result()); |
4999 Register scratch = ToRegister(instr->temp()); | 5013 Register scratch = ToRegister(instr->temp()); |
5000 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5014 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); |
5001 Handle<Map> initial_map(constructor->initial_map()); | 5015 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
5002 int instance_size = initial_map->instance_size(); | 5016 int instance_size = initial_map->instance_size(); |
5003 ASSERT(initial_map->pre_allocated_property_fields() + | 5017 ASSERT(initial_map->pre_allocated_property_fields() + |
5004 initial_map->unused_property_fields() - | 5018 initial_map->unused_property_fields() - |
5005 initial_map->inobject_properties() == 0); | 5019 initial_map->inobject_properties() == 0); |
5006 | 5020 |
5007 // Allocate memory for the object. The initial map might change when | |
5008 // the constructor's prototype changes, but instance size and property | |
5009 // counts remain unchanged (if slack tracking finished). | |
5010 ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); | |
5011 __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(), | 5021 __ Allocate(instance_size, result, no_reg, scratch, deferred->entry(), |
5012 TAG_OBJECT); | 5022 TAG_OBJECT); |
5013 | 5023 |
5014 __ bind(deferred->exit()); | 5024 __ bind(deferred->exit()); |
5015 if (FLAG_debug_code) { | 5025 if (FLAG_debug_code) { |
5016 Label is_in_new_space; | 5026 Label is_in_new_space; |
5017 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); | 5027 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); |
5018 __ Abort("Allocated object is not in new-space"); | 5028 __ Abort("Allocated object is not in new-space"); |
5019 __ bind(&is_in_new_space); | 5029 __ bind(&is_in_new_space); |
5020 } | 5030 } |
(...skipping 30 matching lines...) Expand all Loading... |
5051 for (int i = 0; i < initial_map->inobject_properties(); i++) { | 5061 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
5052 int property_offset = JSObject::kHeaderSize + i * kPointerSize; | 5062 int property_offset = JSObject::kHeaderSize + i * kPointerSize; |
5053 __ movq(FieldOperand(result, property_offset), scratch); | 5063 __ movq(FieldOperand(result, property_offset), scratch); |
5054 } | 5064 } |
5055 } | 5065 } |
5056 } | 5066 } |
5057 | 5067 |
5058 | 5068 |
5059 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { | 5069 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { |
5060 Register result = ToRegister(instr->result()); | 5070 Register result = ToRegister(instr->result()); |
5061 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5071 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
5062 Handle<Map> initial_map(constructor->initial_map()); | |
5063 int instance_size = initial_map->instance_size(); | 5072 int instance_size = initial_map->instance_size(); |
5064 | 5073 |
5065 // TODO(3095996): Get rid of this. For now, we need to make the | 5074 // TODO(3095996): Get rid of this. For now, we need to make the |
5066 // result register contain a valid pointer because it is already | 5075 // result register contain a valid pointer because it is already |
5067 // contained in the register pointer map. | 5076 // contained in the register pointer map. |
5068 __ Set(result, 0); | 5077 __ Set(result, 0); |
5069 | 5078 |
5070 PushSafepointRegistersScope scope(this); | 5079 PushSafepointRegistersScope scope(this); |
5071 __ Push(Smi::FromInt(instance_size)); | 5080 __ Push(Smi::FromInt(instance_size)); |
5072 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); | 5081 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5128 Runtime::kAllocateInOldPointerSpace, 1, instr); | 5137 Runtime::kAllocateInOldPointerSpace, 1, instr); |
5129 } else { | 5138 } else { |
5130 CallRuntimeFromDeferred( | 5139 CallRuntimeFromDeferred( |
5131 Runtime::kAllocateInNewSpace, 1, instr); | 5140 Runtime::kAllocateInNewSpace, 1, instr); |
5132 } | 5141 } |
5133 __ StoreToSafepointRegisterSlot(result, rax); | 5142 __ StoreToSafepointRegisterSlot(result, rax); |
5134 } | 5143 } |
5135 | 5144 |
5136 | 5145 |
5137 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 5146 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
5138 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5147 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
5139 ElementsKind boilerplate_elements_kind = | 5148 ElementsKind boilerplate_elements_kind = |
5140 instr->hydrogen()->boilerplate_elements_kind(); | 5149 instr->hydrogen()->boilerplate_elements_kind(); |
5141 AllocationSiteMode allocation_site_mode = | 5150 AllocationSiteMode allocation_site_mode = |
5142 instr->hydrogen()->allocation_site_mode(); | 5151 instr->hydrogen()->allocation_site_mode(); |
5143 | 5152 |
5144 // Deopt if the array literal boilerplate ElementsKind is of a type different | 5153 // Deopt if the array literal boilerplate ElementsKind is of a type different |
5145 // than the expected one. The check isn't necessary if the boilerplate has | 5154 // than the expected one. The check isn't necessary if the boilerplate has |
5146 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 5155 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
5147 if (CanTransitionToMoreGeneralFastElementsKind( | 5156 if (CanTransitionToMoreGeneralFastElementsKind( |
5148 boilerplate_elements_kind, true)) { | 5157 boilerplate_elements_kind, true)) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5188 boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS | 5197 boilerplate_elements_kind == FAST_DOUBLE_ELEMENTS |
5189 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 5198 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
5190 : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 5199 : FastCloneShallowArrayStub::CLONE_ELEMENTS; |
5191 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 5200 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); |
5192 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5201 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
5193 } | 5202 } |
5194 } | 5203 } |
5195 | 5204 |
5196 | 5205 |
5197 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 5206 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
5198 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5207 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
5199 Handle<FixedArray> constant_properties = | 5208 Handle<FixedArray> constant_properties = |
5200 instr->hydrogen()->constant_properties(); | 5209 instr->hydrogen()->constant_properties(); |
5201 | 5210 |
5202 int flags = instr->hydrogen()->fast_elements() | 5211 int flags = instr->hydrogen()->fast_elements() |
5203 ? ObjectLiteral::kFastElements | 5212 ? ObjectLiteral::kFastElements |
5204 : ObjectLiteral::kNoFlags; | 5213 : ObjectLiteral::kNoFlags; |
5205 flags |= instr->hydrogen()->has_function() | 5214 flags |= instr->hydrogen()->has_function() |
5206 ? ObjectLiteral::kHasFunction | 5215 ? ObjectLiteral::kHasFunction |
5207 : ObjectLiteral::kNoFlags; | 5216 : ObjectLiteral::kNoFlags; |
5208 | 5217 |
5209 // Set up the parameters to the stub/runtime call and pick the right | 5218 // Set up the parameters to the stub/runtime call and pick the right |
5210 // runtime function or stub to call. | 5219 // runtime function or stub to call. |
5211 int properties_count = constant_properties->length() / 2; | 5220 int properties_count = instr->hydrogen()->constant_properties_length() / 2; |
5212 if (instr->hydrogen()->depth() > 1) { | 5221 if (instr->hydrogen()->depth() > 1) { |
5213 __ PushHeapObject(literals); | 5222 __ PushHeapObject(literals); |
5214 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); | 5223 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); |
5215 __ Push(constant_properties); | 5224 __ Push(constant_properties); |
5216 __ Push(Smi::FromInt(flags)); | 5225 __ Push(Smi::FromInt(flags)); |
5217 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); | 5226 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); |
5218 } else if (flags != ObjectLiteral::kFastElements || | 5227 } else if (flags != ObjectLiteral::kFastElements || |
5219 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 5228 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
5220 __ PushHeapObject(literals); | 5229 __ PushHeapObject(literals); |
5221 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); | 5230 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5286 if ((size % (2 * kPointerSize)) != 0) { | 5295 if ((size % (2 * kPointerSize)) != 0) { |
5287 __ movq(rdx, FieldOperand(rbx, size - kPointerSize)); | 5296 __ movq(rdx, FieldOperand(rbx, size - kPointerSize)); |
5288 __ movq(FieldOperand(rax, size - kPointerSize), rdx); | 5297 __ movq(FieldOperand(rax, size - kPointerSize), rdx); |
5289 } | 5298 } |
5290 } | 5299 } |
5291 | 5300 |
5292 | 5301 |
5293 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 5302 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
5294 // Use the fast case closure allocation code that allocates in new | 5303 // Use the fast case closure allocation code that allocates in new |
5295 // space for nested functions that don't need literals cloning. | 5304 // space for nested functions that don't need literals cloning. |
5296 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | |
5297 bool pretenure = instr->hydrogen()->pretenure(); | 5305 bool pretenure = instr->hydrogen()->pretenure(); |
5298 if (!pretenure && shared_info->num_literals() == 0) { | 5306 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
5299 FastNewClosureStub stub(shared_info->language_mode(), | 5307 FastNewClosureStub stub(instr->hydrogen()->language_mode(), |
5300 shared_info->is_generator()); | 5308 instr->hydrogen()->is_generator()); |
5301 __ Push(shared_info); | 5309 __ Push(instr->hydrogen()->shared_info()); |
5302 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5310 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
5303 } else { | 5311 } else { |
5304 __ push(rsi); | 5312 __ push(rsi); |
5305 __ Push(shared_info); | 5313 __ Push(instr->hydrogen()->shared_info()); |
5306 __ PushRoot(pretenure ? | 5314 __ PushRoot(pretenure ? Heap::kTrueValueRootIndex : |
5307 Heap::kTrueValueRootIndex : | 5315 Heap::kFalseValueRootIndex); |
5308 Heap::kFalseValueRootIndex); | |
5309 CallRuntime(Runtime::kNewClosure, 3, instr); | 5316 CallRuntime(Runtime::kNewClosure, 3, instr); |
5310 } | 5317 } |
5311 } | 5318 } |
5312 | 5319 |
5313 | 5320 |
5314 void LCodeGen::DoTypeof(LTypeof* instr) { | 5321 void LCodeGen::DoTypeof(LTypeof* instr) { |
5315 LOperand* input = instr->value(); | 5322 LOperand* input = instr->value(); |
5316 EmitPushTaggedOperand(input); | 5323 EmitPushTaggedOperand(input); |
5317 CallRuntime(Runtime::kTypeof, 1, instr); | 5324 CallRuntime(Runtime::kTypeof, 1, instr); |
5318 } | 5325 } |
5319 | 5326 |
5320 | 5327 |
5321 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { | 5328 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
5322 ASSERT(!operand->IsDoubleRegister()); | 5329 ASSERT(!operand->IsDoubleRegister()); |
5323 if (operand->IsConstantOperand()) { | 5330 if (operand->IsConstantOperand()) { |
5324 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); | 5331 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); |
| 5332 ALLOW_HANDLE_DEREF(isolate(), "smi check"); |
5325 if (object->IsSmi()) { | 5333 if (object->IsSmi()) { |
5326 __ Push(Handle<Smi>::cast(object)); | 5334 __ Push(Handle<Smi>::cast(object)); |
5327 } else { | 5335 } else { |
5328 __ PushHeapObject(Handle<HeapObject>::cast(object)); | 5336 __ PushHeapObject(Handle<HeapObject>::cast(object)); |
5329 } | 5337 } |
5330 } else if (operand->IsRegister()) { | 5338 } else if (operand->IsRegister()) { |
5331 __ push(ToRegister(operand)); | 5339 __ push(ToRegister(operand)); |
5332 } else { | 5340 } else { |
5333 __ push(ToOperand(operand)); | 5341 __ push(ToOperand(operand)); |
5334 } | 5342 } |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5679 FixedArray::kHeaderSize - kPointerSize)); | 5687 FixedArray::kHeaderSize - kPointerSize)); |
5680 __ bind(&done); | 5688 __ bind(&done); |
5681 } | 5689 } |
5682 | 5690 |
5683 | 5691 |
5684 #undef __ | 5692 #undef __ |
5685 | 5693 |
5686 } } // namespace v8::internal | 5694 } } // namespace v8::internal |
5687 | 5695 |
5688 #endif // V8_TARGET_ARCH_X64 | 5696 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |