Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 14403015: Disallow dereferencing deferred handles when generating optimized code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698