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 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 // values on the stack that represent the arguments. This needs to be | 569 // values on the stack that represent the arguments. This needs to be |
570 // kept in sync with the LArgumentsElements implementation. | 570 // kept in sync with the LArgumentsElements implementation. |
571 *pushed_arguments_index = -environment->parameter_count(); | 571 *pushed_arguments_index = -environment->parameter_count(); |
572 *pushed_arguments_count = environment->parameter_count(); | 572 *pushed_arguments_count = environment->parameter_count(); |
573 | 573 |
574 WriteTranslation(environment->outer(), | 574 WriteTranslation(environment->outer(), |
575 translation, | 575 translation, |
576 pushed_arguments_index, | 576 pushed_arguments_index, |
577 pushed_arguments_count); | 577 pushed_arguments_count); |
578 bool has_closure_id = !info()->closure().is_null() && | 578 bool has_closure_id = !info()->closure().is_null() && |
579 *info()->closure() != *environment->closure(); | 579 !info()->closure().is_identical_to(environment->closure()); |
580 int closure_id = has_closure_id | 580 int closure_id = has_closure_id |
581 ? DefineDeoptimizationLiteral(environment->closure()) | 581 ? DefineDeoptimizationLiteral(environment->closure()) |
582 : Translation::kSelfLiteralId; | 582 : Translation::kSelfLiteralId; |
583 | 583 |
584 switch (environment->frame_type()) { | 584 switch (environment->frame_type()) { |
585 case JS_FUNCTION: | 585 case JS_FUNCTION: |
586 translation->BeginJSFrame(environment->ast_id(), closure_id, height); | 586 translation->BeginJSFrame(environment->ast_id(), closure_id, height); |
587 break; | 587 break; |
588 case JS_CONSTRUCT: | 588 case JS_CONSTRUCT: |
589 translation->BeginConstructStubFrame(closure_id, translation_size); | 589 translation->BeginConstructStubFrame(closure_id, translation_size); |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 Handle<DeoptimizationInputData> data = | 881 Handle<DeoptimizationInputData> data = |
882 factory()->NewDeoptimizationInputData(length, TENURED); | 882 factory()->NewDeoptimizationInputData(length, TENURED); |
883 | 883 |
884 Handle<ByteArray> translations = | 884 Handle<ByteArray> translations = |
885 translations_.CreateByteArray(isolate()->factory()); | 885 translations_.CreateByteArray(isolate()->factory()); |
886 data->SetTranslationByteArray(*translations); | 886 data->SetTranslationByteArray(*translations); |
887 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); | 887 data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_)); |
888 | 888 |
889 Handle<FixedArray> literals = | 889 Handle<FixedArray> literals = |
890 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 890 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
891 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 891 { ALLOW_HANDLE_DEREF(isolate(), |
892 literals->set(i, *deoptimization_literals_[i]); | 892 "copying a ZoneList of handles into a FixedArray"); |
| 893 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
| 894 literals->set(i, *deoptimization_literals_[i]); |
| 895 } |
| 896 data->SetLiteralArray(*literals); |
893 } | 897 } |
894 data->SetLiteralArray(*literals); | |
895 | 898 |
896 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 899 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
897 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 900 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
898 | 901 |
899 // Populate the deoptimization entries. | 902 // Populate the deoptimization entries. |
900 for (int i = 0; i < length; i++) { | 903 for (int i = 0; i < length; i++) { |
901 LEnvironment* env = deoptimizations_[i]; | 904 LEnvironment* env = deoptimizations_[i]; |
902 data->SetAstId(i, env->ast_id()); | 905 data->SetAstId(i, env->ast_id()); |
903 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 906 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
904 data->SetArgumentsStackHeight(i, | 907 data->SetArgumentsStackHeight(i, |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1466 void LCodeGen::DoConstantD(LConstantD* instr) { | 1469 void LCodeGen::DoConstantD(LConstantD* instr) { |
1467 ASSERT(instr->result()->IsDoubleRegister()); | 1470 ASSERT(instr->result()->IsDoubleRegister()); |
1468 DoubleRegister result = ToDoubleRegister(instr->result()); | 1471 DoubleRegister result = ToDoubleRegister(instr->result()); |
1469 double v = instr->value(); | 1472 double v = instr->value(); |
1470 __ Move(result, v); | 1473 __ Move(result, v); |
1471 } | 1474 } |
1472 | 1475 |
1473 | 1476 |
1474 void LCodeGen::DoConstantT(LConstantT* instr) { | 1477 void LCodeGen::DoConstantT(LConstantT* instr) { |
1475 Handle<Object> value = instr->value(); | 1478 Handle<Object> value = instr->value(); |
| 1479 ALLOW_HANDLE_DEREF(isolate(), "smi check"); |
1476 if (value->IsSmi()) { | 1480 if (value->IsSmi()) { |
1477 __ li(ToRegister(instr->result()), Operand(value)); | 1481 __ li(ToRegister(instr->result()), Operand(value)); |
1478 } else { | 1482 } else { |
1479 __ LoadHeapObject(ToRegister(instr->result()), | 1483 __ LoadHeapObject(ToRegister(instr->result()), |
1480 Handle<HeapObject>::cast(value)); | 1484 Handle<HeapObject>::cast(value)); |
1481 } | 1485 } |
1482 } | 1486 } |
1483 | 1487 |
1484 | 1488 |
1485 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { | 1489 void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) { |
(...skipping 1828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3314 | 3318 |
3315 | 3319 |
3316 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { | 3320 void LCodeGen::DoGlobalReceiver(LGlobalReceiver* instr) { |
3317 Register global = ToRegister(instr->global_object()); | 3321 Register global = ToRegister(instr->global_object()); |
3318 Register result = ToRegister(instr->result()); | 3322 Register result = ToRegister(instr->result()); |
3319 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); | 3323 __ lw(result, FieldMemOperand(global, GlobalObject::kGlobalReceiverOffset)); |
3320 } | 3324 } |
3321 | 3325 |
3322 | 3326 |
3323 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, | 3327 void LCodeGen::CallKnownFunction(Handle<JSFunction> function, |
| 3328 int formal_parameter_count, |
3324 int arity, | 3329 int arity, |
3325 LInstruction* instr, | 3330 LInstruction* instr, |
3326 CallKind call_kind, | 3331 CallKind call_kind, |
3327 A1State a1_state) { | 3332 A1State a1_state) { |
3328 bool can_invoke_directly = !function->NeedsArgumentsAdaption() || | 3333 bool dont_adapt_arguments = |
3329 function->shared()->formal_parameter_count() == arity; | 3334 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3335 bool can_invoke_directly = |
| 3336 dont_adapt_arguments || formal_parameter_count == arity; |
3330 | 3337 |
3331 LPointerMap* pointers = instr->pointer_map(); | 3338 LPointerMap* pointers = instr->pointer_map(); |
3332 RecordPosition(pointers->position()); | 3339 RecordPosition(pointers->position()); |
3333 | 3340 |
3334 if (can_invoke_directly) { | 3341 if (can_invoke_directly) { |
3335 if (a1_state == A1_UNINITIALIZED) { | 3342 if (a1_state == A1_UNINITIALIZED) { |
3336 __ LoadHeapObject(a1, function); | 3343 __ LoadHeapObject(a1, function); |
3337 } | 3344 } |
3338 | 3345 |
3339 // Change context. | 3346 // Change context. |
3340 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 3347 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
3341 | 3348 |
3342 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | 3349 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
3343 // is available to write to at this point. | 3350 // is available to write to at this point. |
3344 if (!function->NeedsArgumentsAdaption()) { | 3351 if (dont_adapt_arguments) { |
3345 __ li(a0, Operand(arity)); | 3352 __ li(a0, Operand(arity)); |
3346 } | 3353 } |
3347 | 3354 |
3348 // Invoke function. | 3355 // Invoke function. |
3349 __ SetCallKind(t1, call_kind); | 3356 __ SetCallKind(t1, call_kind); |
3350 __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 3357 __ lw(at, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
3351 __ Call(at); | 3358 __ Call(at); |
3352 | 3359 |
3353 // Set up deoptimization. | 3360 // Set up deoptimization. |
3354 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 3361 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
3355 } else { | 3362 } else { |
3356 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3363 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3357 ParameterCount count(arity); | 3364 ParameterCount count(arity); |
3358 __ InvokeFunction(function, count, CALL_FUNCTION, generator, call_kind); | 3365 ParameterCount expected(formal_parameter_count); |
| 3366 __ InvokeFunction( |
| 3367 function, expected, count, CALL_FUNCTION, generator, call_kind); |
3359 } | 3368 } |
3360 | 3369 |
3361 // Restore context. | 3370 // Restore context. |
3362 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3371 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3363 } | 3372 } |
3364 | 3373 |
3365 | 3374 |
3366 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 3375 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
3367 ASSERT(ToRegister(instr->result()).is(v0)); | 3376 ASSERT(ToRegister(instr->result()).is(v0)); |
3368 __ mov(a0, v0); | 3377 __ mov(a0, v0); |
3369 CallKnownFunction(instr->function(), | 3378 CallKnownFunction(instr->hydrogen()->function(), |
| 3379 instr->hydrogen()->formal_parameter_count(), |
3370 instr->arity(), | 3380 instr->arity(), |
3371 instr, | 3381 instr, |
3372 CALL_AS_METHOD, | 3382 CALL_AS_METHOD, |
3373 A1_UNINITIALIZED); | 3383 A1_UNINITIALIZED); |
3374 } | 3384 } |
3375 | 3385 |
3376 | 3386 |
3377 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3387 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
3378 Register input = ToRegister(instr->value()); | 3388 Register input = ToRegister(instr->value()); |
3379 Register result = ToRegister(instr->result()); | 3389 Register result = ToRegister(instr->result()); |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3771 TranscendentalCacheStub stub(TranscendentalCache::SIN, | 3781 TranscendentalCacheStub stub(TranscendentalCache::SIN, |
3772 TranscendentalCacheStub::UNTAGGED); | 3782 TranscendentalCacheStub::UNTAGGED); |
3773 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3783 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
3774 } | 3784 } |
3775 | 3785 |
3776 | 3786 |
3777 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3787 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
3778 ASSERT(ToRegister(instr->function()).is(a1)); | 3788 ASSERT(ToRegister(instr->function()).is(a1)); |
3779 ASSERT(instr->HasPointerMap()); | 3789 ASSERT(instr->HasPointerMap()); |
3780 | 3790 |
3781 if (instr->known_function().is_null()) { | 3791 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 3792 if (known_function.is_null()) { |
3782 LPointerMap* pointers = instr->pointer_map(); | 3793 LPointerMap* pointers = instr->pointer_map(); |
3783 RecordPosition(pointers->position()); | 3794 RecordPosition(pointers->position()); |
3784 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3795 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
3785 ParameterCount count(instr->arity()); | 3796 ParameterCount count(instr->arity()); |
3786 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 3797 __ InvokeFunction(a1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
3787 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3798 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3788 } else { | 3799 } else { |
3789 CallKnownFunction(instr->known_function(), | 3800 CallKnownFunction(known_function, |
| 3801 instr->hydrogen()->formal_parameter_count(), |
3790 instr->arity(), | 3802 instr->arity(), |
3791 instr, | 3803 instr, |
3792 CALL_AS_METHOD, | 3804 CALL_AS_METHOD, |
3793 A1_CONTAINS_TARGET); | 3805 A1_CONTAINS_TARGET); |
3794 } | 3806 } |
3795 } | 3807 } |
3796 | 3808 |
3797 | 3809 |
3798 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { | 3810 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { |
3799 ASSERT(ToRegister(instr->result()).is(v0)); | 3811 ASSERT(ToRegister(instr->result()).is(v0)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3839 Handle<Code> ic = | 3851 Handle<Code> ic = |
3840 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); | 3852 isolate()->stub_cache()->ComputeCallInitialize(arity, mode); |
3841 __ li(a2, Operand(instr->name())); | 3853 __ li(a2, Operand(instr->name())); |
3842 CallCode(ic, mode, instr); | 3854 CallCode(ic, mode, instr); |
3843 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3855 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
3844 } | 3856 } |
3845 | 3857 |
3846 | 3858 |
3847 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { | 3859 void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { |
3848 ASSERT(ToRegister(instr->result()).is(v0)); | 3860 ASSERT(ToRegister(instr->result()).is(v0)); |
3849 CallKnownFunction(instr->target(), | 3861 CallKnownFunction(instr->hydrogen()->target(), |
| 3862 instr->hydrogen()->formal_parameter_count(), |
3850 instr->arity(), | 3863 instr->arity(), |
3851 instr, | 3864 instr, |
3852 CALL_AS_FUNCTION, | 3865 CALL_AS_FUNCTION, |
3853 A1_UNINITIALIZED); | 3866 A1_UNINITIALIZED); |
3854 } | 3867 } |
3855 | 3868 |
3856 | 3869 |
3857 void LCodeGen::DoCallNew(LCallNew* instr) { | 3870 void LCodeGen::DoCallNew(LCallNew* instr) { |
3858 ASSERT(ToRegister(instr->constructor()).is(a1)); | 3871 ASSERT(ToRegister(instr->constructor()).is(a1)); |
3859 ASSERT(ToRegister(instr->result()).is(v0)); | 3872 ASSERT(ToRegister(instr->result()).is(v0)); |
(...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4881 __ And(scratch, scratch, Operand(mask)); | 4894 __ And(scratch, scratch, Operand(mask)); |
4882 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); | 4895 DeoptimizeIf(ne, instr->environment(), scratch, Operand(tag)); |
4883 } | 4896 } |
4884 } | 4897 } |
4885 } | 4898 } |
4886 | 4899 |
4887 | 4900 |
4888 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { | 4901 void LCodeGen::DoCheckFunction(LCheckFunction* instr) { |
4889 Register reg = ToRegister(instr->value()); | 4902 Register reg = ToRegister(instr->value()); |
4890 Handle<JSFunction> target = instr->hydrogen()->target(); | 4903 Handle<JSFunction> target = instr->hydrogen()->target(); |
| 4904 ALLOW_HANDLE_DEREF(isolate(), "smi check"); |
4891 if (isolate()->heap()->InNewSpace(*target)) { | 4905 if (isolate()->heap()->InNewSpace(*target)) { |
4892 Register reg = ToRegister(instr->value()); | 4906 Register reg = ToRegister(instr->value()); |
4893 Handle<JSGlobalPropertyCell> cell = | 4907 Handle<JSGlobalPropertyCell> cell = |
4894 isolate()->factory()->NewJSGlobalPropertyCell(target); | 4908 isolate()->factory()->NewJSGlobalPropertyCell(target); |
4895 __ li(at, Operand(Handle<Object>(cell))); | 4909 __ li(at, Operand(Handle<Object>(cell))); |
4896 __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); | 4910 __ lw(at, FieldMemOperand(at, JSGlobalPropertyCell::kValueOffset)); |
4897 DeoptimizeIf(ne, instr->environment(), reg, | 4911 DeoptimizeIf(ne, instr->environment(), reg, |
4898 Operand(at)); | 4912 Operand(at)); |
4899 } else { | 4913 } else { |
4900 DeoptimizeIf(ne, instr->environment(), reg, | 4914 DeoptimizeIf(ne, instr->environment(), reg, |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5020 LAllocateObject* instr_; | 5034 LAllocateObject* instr_; |
5021 }; | 5035 }; |
5022 | 5036 |
5023 DeferredAllocateObject* deferred = | 5037 DeferredAllocateObject* deferred = |
5024 new(zone()) DeferredAllocateObject(this, instr); | 5038 new(zone()) DeferredAllocateObject(this, instr); |
5025 | 5039 |
5026 Register result = ToRegister(instr->result()); | 5040 Register result = ToRegister(instr->result()); |
5027 Register scratch = ToRegister(instr->temp()); | 5041 Register scratch = ToRegister(instr->temp()); |
5028 Register scratch2 = ToRegister(instr->temp2()); | 5042 Register scratch2 = ToRegister(instr->temp2()); |
5029 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5043 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); |
5030 Handle<Map> initial_map(constructor->initial_map()); | 5044 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
5031 int instance_size = initial_map->instance_size(); | 5045 int instance_size = initial_map->instance_size(); |
5032 ASSERT(initial_map->pre_allocated_property_fields() + | 5046 ASSERT(initial_map->pre_allocated_property_fields() + |
5033 initial_map->unused_property_fields() - | 5047 initial_map->unused_property_fields() - |
5034 initial_map->inobject_properties() == 0); | 5048 initial_map->inobject_properties() == 0); |
5035 | 5049 |
5036 // Allocate memory for the object. The initial map might change when | |
5037 // the constructor's prototype changes, but instance size and property | |
5038 // counts remain unchanged (if slack tracking finished). | |
5039 ASSERT(!constructor->shared()->IsInobjectSlackTrackingInProgress()); | |
5040 __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(), | 5050 __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(), |
5041 TAG_OBJECT); | 5051 TAG_OBJECT); |
5042 | 5052 |
5043 __ bind(deferred->exit()); | 5053 __ bind(deferred->exit()); |
5044 if (FLAG_debug_code) { | 5054 if (FLAG_debug_code) { |
5045 Label is_in_new_space; | 5055 Label is_in_new_space; |
5046 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); | 5056 __ JumpIfInNewSpace(result, scratch, &is_in_new_space); |
5047 __ Abort("Allocated object is not in new-space"); | 5057 __ Abort("Allocated object is not in new-space"); |
5048 __ bind(&is_in_new_space); | 5058 __ bind(&is_in_new_space); |
5049 } | 5059 } |
(...skipping 14 matching lines...) Expand all Loading... |
5064 for (int i = 0; i < initial_map->inobject_properties(); i++) { | 5074 for (int i = 0; i < initial_map->inobject_properties(); i++) { |
5065 int property_offset = JSObject::kHeaderSize + i * kPointerSize; | 5075 int property_offset = JSObject::kHeaderSize + i * kPointerSize; |
5066 __ sw(scratch, FieldMemOperand(result, property_offset)); | 5076 __ sw(scratch, FieldMemOperand(result, property_offset)); |
5067 } | 5077 } |
5068 } | 5078 } |
5069 } | 5079 } |
5070 | 5080 |
5071 | 5081 |
5072 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { | 5082 void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) { |
5073 Register result = ToRegister(instr->result()); | 5083 Register result = ToRegister(instr->result()); |
5074 Handle<JSFunction> constructor = instr->hydrogen()->constructor(); | 5084 Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map(); |
5075 Handle<Map> initial_map(constructor->initial_map()); | |
5076 int instance_size = initial_map->instance_size(); | 5085 int instance_size = initial_map->instance_size(); |
5077 | 5086 |
5078 // TODO(3095996): Get rid of this. For now, we need to make the | 5087 // TODO(3095996): Get rid of this. For now, we need to make the |
5079 // result register contain a valid pointer because it is already | 5088 // result register contain a valid pointer because it is already |
5080 // contained in the register pointer map. | 5089 // contained in the register pointer map. |
5081 __ mov(result, zero_reg); | 5090 __ mov(result, zero_reg); |
5082 | 5091 |
5083 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 5092 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
5084 __ li(a0, Operand(Smi::FromInt(instance_size))); | 5093 __ li(a0, Operand(Smi::FromInt(instance_size))); |
5085 __ push(a0); | 5094 __ push(a0); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5148 Runtime::kAllocateInOldPointerSpace, 1, instr); | 5157 Runtime::kAllocateInOldPointerSpace, 1, instr); |
5149 } else { | 5158 } else { |
5150 CallRuntimeFromDeferred( | 5159 CallRuntimeFromDeferred( |
5151 Runtime::kAllocateInNewSpace, 1, instr); | 5160 Runtime::kAllocateInNewSpace, 1, instr); |
5152 } | 5161 } |
5153 __ StoreToSafepointRegisterSlot(v0, result); | 5162 __ StoreToSafepointRegisterSlot(v0, result); |
5154 } | 5163 } |
5155 | 5164 |
5156 | 5165 |
5157 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { | 5166 void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { |
5158 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5167 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
5159 ElementsKind boilerplate_elements_kind = | 5168 ElementsKind boilerplate_elements_kind = |
5160 instr->hydrogen()->boilerplate_elements_kind(); | 5169 instr->hydrogen()->boilerplate_elements_kind(); |
5161 AllocationSiteMode allocation_site_mode = | 5170 AllocationSiteMode allocation_site_mode = |
5162 instr->hydrogen()->allocation_site_mode(); | 5171 instr->hydrogen()->allocation_site_mode(); |
5163 | 5172 |
5164 // Deopt if the array literal boilerplate ElementsKind is of a type different | 5173 // Deopt if the array literal boilerplate ElementsKind is of a type different |
5165 // than the expected one. The check isn't necessary if the boilerplate has | 5174 // than the expected one. The check isn't necessary if the boilerplate has |
5166 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. | 5175 // already been converted to TERMINAL_FAST_ELEMENTS_KIND. |
5167 if (CanTransitionToMoreGeneralFastElementsKind( | 5176 if (CanTransitionToMoreGeneralFastElementsKind( |
5168 boilerplate_elements_kind, true)) { | 5177 boilerplate_elements_kind, true)) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5206 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS | 5215 ? FastCloneShallowArrayStub::CLONE_DOUBLE_ELEMENTS |
5207 : FastCloneShallowArrayStub::CLONE_ELEMENTS; | 5216 : FastCloneShallowArrayStub::CLONE_ELEMENTS; |
5208 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); | 5217 FastCloneShallowArrayStub stub(mode, allocation_site_mode, length); |
5209 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5218 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
5210 } | 5219 } |
5211 } | 5220 } |
5212 | 5221 |
5213 | 5222 |
5214 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { | 5223 void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { |
5215 ASSERT(ToRegister(instr->result()).is(v0)); | 5224 ASSERT(ToRegister(instr->result()).is(v0)); |
5216 Handle<FixedArray> literals(instr->environment()->closure()->literals()); | 5225 Handle<FixedArray> literals = instr->hydrogen()->literals(); |
5217 Handle<FixedArray> constant_properties = | 5226 Handle<FixedArray> constant_properties = |
5218 instr->hydrogen()->constant_properties(); | 5227 instr->hydrogen()->constant_properties(); |
5219 | 5228 |
5220 // Set up the parameters to the stub/runtime call. | 5229 // Set up the parameters to the stub/runtime call. |
5221 __ LoadHeapObject(a3, literals); | 5230 __ LoadHeapObject(a3, literals); |
5222 __ li(a2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); | 5231 __ li(a2, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
5223 __ li(a1, Operand(constant_properties)); | 5232 __ li(a1, Operand(constant_properties)); |
5224 int flags = instr->hydrogen()->fast_elements() | 5233 int flags = instr->hydrogen()->fast_elements() |
5225 ? ObjectLiteral::kFastElements | 5234 ? ObjectLiteral::kFastElements |
5226 : ObjectLiteral::kNoFlags; | 5235 : ObjectLiteral::kNoFlags; |
5227 __ li(a0, Operand(Smi::FromInt(flags))); | 5236 __ li(a0, Operand(Smi::FromInt(flags))); |
5228 | 5237 |
5229 // Pick the right runtime function or stub to call. | 5238 // Pick the right runtime function or stub to call. |
5230 int properties_count = constant_properties->length() / 2; | 5239 int properties_count = instr->hydrogen()->constant_properties_length() / 2; |
5231 if (instr->hydrogen()->depth() > 1) { | 5240 if (instr->hydrogen()->depth() > 1) { |
5232 __ Push(a3, a2, a1, a0); | 5241 __ Push(a3, a2, a1, a0); |
5233 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); | 5242 CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); |
5234 } else if (flags != ObjectLiteral::kFastElements || | 5243 } else if (flags != ObjectLiteral::kFastElements || |
5235 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { | 5244 properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) { |
5236 __ Push(a3, a2, a1, a0); | 5245 __ Push(a3, a2, a1, a0); |
5237 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); | 5246 CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); |
5238 } else { | 5247 } else { |
5239 FastCloneShallowObjectStub stub(properties_count); | 5248 FastCloneShallowObjectStub stub(properties_count); |
5240 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5249 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5298 if ((size % (2 * kPointerSize)) != 0) { | 5307 if ((size % (2 * kPointerSize)) != 0) { |
5299 __ lw(a3, FieldMemOperand(a1, size - kPointerSize)); | 5308 __ lw(a3, FieldMemOperand(a1, size - kPointerSize)); |
5300 __ sw(a3, FieldMemOperand(v0, size - kPointerSize)); | 5309 __ sw(a3, FieldMemOperand(v0, size - kPointerSize)); |
5301 } | 5310 } |
5302 } | 5311 } |
5303 | 5312 |
5304 | 5313 |
5305 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 5314 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
5306 // Use the fast case closure allocation code that allocates in new | 5315 // Use the fast case closure allocation code that allocates in new |
5307 // space for nested functions that don't need literals cloning. | 5316 // space for nested functions that don't need literals cloning. |
5308 Handle<SharedFunctionInfo> shared_info = instr->shared_info(); | |
5309 bool pretenure = instr->hydrogen()->pretenure(); | 5317 bool pretenure = instr->hydrogen()->pretenure(); |
5310 if (!pretenure && shared_info->num_literals() == 0) { | 5318 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
5311 FastNewClosureStub stub(shared_info->language_mode(), | 5319 FastNewClosureStub stub(instr->hydrogen()->language_mode(), |
5312 shared_info->is_generator()); | 5320 instr->hydrogen()->is_generator()); |
5313 __ li(a1, Operand(shared_info)); | 5321 __ li(a1, Operand(instr->hydrogen()->shared_info())); |
5314 __ push(a1); | 5322 __ push(a1); |
5315 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5323 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
5316 } else { | 5324 } else { |
5317 __ li(a2, Operand(shared_info)); | 5325 __ li(a2, Operand(instr->hydrogen()->shared_info())); |
5318 __ li(a1, Operand(pretenure | 5326 __ li(a1, Operand(pretenure ? factory()->true_value() |
5319 ? factory()->true_value() | 5327 : factory()->false_value())); |
5320 : factory()->false_value())); | |
5321 __ Push(cp, a2, a1); | 5328 __ Push(cp, a2, a1); |
5322 CallRuntime(Runtime::kNewClosure, 3, instr); | 5329 CallRuntime(Runtime::kNewClosure, 3, instr); |
5323 } | 5330 } |
5324 } | 5331 } |
5325 | 5332 |
5326 | 5333 |
5327 void LCodeGen::DoTypeof(LTypeof* instr) { | 5334 void LCodeGen::DoTypeof(LTypeof* instr) { |
5328 ASSERT(ToRegister(instr->result()).is(v0)); | 5335 ASSERT(ToRegister(instr->result()).is(v0)); |
5329 Register input = ToRegister(instr->value()); | 5336 Register input = ToRegister(instr->value()); |
5330 __ push(input); | 5337 __ push(input); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5718 __ Subu(scratch, result, scratch); | 5725 __ Subu(scratch, result, scratch); |
5719 __ lw(result, FieldMemOperand(scratch, | 5726 __ lw(result, FieldMemOperand(scratch, |
5720 FixedArray::kHeaderSize - kPointerSize)); | 5727 FixedArray::kHeaderSize - kPointerSize)); |
5721 __ bind(&done); | 5728 __ bind(&done); |
5722 } | 5729 } |
5723 | 5730 |
5724 | 5731 |
5725 #undef __ | 5732 #undef __ |
5726 | 5733 |
5727 } } // namespace v8::internal | 5734 } } // namespace v8::internal |
OLD | NEW |