| 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 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 if (FLAG_code_comments && instr->HasInterestingComment(this)) { | 270 if (FLAG_code_comments && instr->HasInterestingComment(this)) { |
| 271 Comment(";;; <@%d,#%d> %s", | 271 Comment(";;; <@%d,#%d> %s", |
| 272 current_instruction_, | 272 current_instruction_, |
| 273 instr->hydrogen_value()->id(), | 273 instr->hydrogen_value()->id(), |
| 274 instr->Mnemonic()); | 274 instr->Mnemonic()); |
| 275 } | 275 } |
| 276 | 276 |
| 277 instr->CompileToNative(this); | 277 instr->CompileToNative(this); |
| 278 } | 278 } |
| 279 EnsureSpaceForLazyDeopt(); | 279 EnsureSpaceForLazyDeopt(); |
| 280 last_lazy_deopt_pc_ = masm()->pc_offset(); |
| 280 return !is_aborted(); | 281 return !is_aborted(); |
| 281 } | 282 } |
| 282 | 283 |
| 283 | 284 |
| 284 bool LCodeGen::GenerateDeferredCode() { | 285 bool LCodeGen::GenerateDeferredCode() { |
| 285 ASSERT(is_generating()); | 286 ASSERT(is_generating()); |
| 286 if (deferred_.length() > 0) { | 287 if (deferred_.length() > 0) { |
| 287 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 288 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 288 LDeferredCode* code = deferred_[i]; | 289 LDeferredCode* code = deferred_[i]; |
| 289 Comment(";;; <@%d,#%d> " | 290 Comment(";;; <@%d,#%d> " |
| (...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 TargetAddressStorageMode storage_mode) { | 670 TargetAddressStorageMode storage_mode) { |
| 670 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode); | 671 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode); |
| 671 } | 672 } |
| 672 | 673 |
| 673 | 674 |
| 674 void LCodeGen::CallCodeGeneric(Handle<Code> code, | 675 void LCodeGen::CallCodeGeneric(Handle<Code> code, |
| 675 RelocInfo::Mode mode, | 676 RelocInfo::Mode mode, |
| 676 LInstruction* instr, | 677 LInstruction* instr, |
| 677 SafepointMode safepoint_mode, | 678 SafepointMode safepoint_mode, |
| 678 TargetAddressStorageMode storage_mode) { | 679 TargetAddressStorageMode storage_mode) { |
| 680 EnsureSpaceForLazyDeopt(); |
| 679 ASSERT(instr != NULL); | 681 ASSERT(instr != NULL); |
| 680 // Block literal pool emission to ensure nop indicating no inlined smi code | 682 // Block literal pool emission to ensure nop indicating no inlined smi code |
| 681 // is in the correct position. | 683 // is in the correct position. |
| 682 Assembler::BlockConstPoolScope block_const_pool(masm()); | 684 Assembler::BlockConstPoolScope block_const_pool(masm()); |
| 683 LPointerMap* pointers = instr->pointer_map(); | 685 LPointerMap* pointers = instr->pointer_map(); |
| 684 RecordPosition(pointers->position()); | 686 RecordPosition(pointers->position()); |
| 685 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); | 687 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); |
| 686 RecordSafepointWithLazyDeopt(instr, safepoint_mode); | 688 RecordSafepointWithLazyDeopt(instr, safepoint_mode); |
| 687 | 689 |
| 688 // Signal that we don't inline smi code before these stubs in the | 690 // Signal that we don't inline smi code before these stubs in the |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1034 case CodeStub::SubString: { | 1036 case CodeStub::SubString: { |
| 1035 SubStringStub stub; | 1037 SubStringStub stub; |
| 1036 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1038 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1037 break; | 1039 break; |
| 1038 } | 1040 } |
| 1039 case CodeStub::NumberToString: { | 1041 case CodeStub::NumberToString: { |
| 1040 NumberToStringStub stub; | 1042 NumberToStringStub stub; |
| 1041 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1043 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1042 break; | 1044 break; |
| 1043 } | 1045 } |
| 1044 case CodeStub::StringAdd: { | |
| 1045 StringAddStub stub(NO_STRING_ADD_FLAGS); | |
| 1046 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | |
| 1047 break; | |
| 1048 } | |
| 1049 case CodeStub::StringCompare: { | 1046 case CodeStub::StringCompare: { |
| 1050 StringCompareStub stub; | 1047 StringCompareStub stub; |
| 1051 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1048 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 1052 break; | 1049 break; |
| 1053 } | 1050 } |
| 1054 case CodeStub::TranscendentalCache: { | 1051 case CodeStub::TranscendentalCache: { |
| 1055 __ ldr(r0, MemOperand(sp, 0)); | 1052 __ ldr(r0, MemOperand(sp, 0)); |
| 1056 TranscendentalCacheStub stub(instr->transcendental_type(), | 1053 TranscendentalCacheStub stub(instr->transcendental_type(), |
| 1057 TranscendentalCacheStub::TAGGED); | 1054 TranscendentalCacheStub::TAGGED); |
| 1058 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1055 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| (...skipping 1862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2921 ASSERT(ToRegister(instr->value()).is(r0)); | 2918 ASSERT(ToRegister(instr->value()).is(r0)); |
| 2922 | 2919 |
| 2923 __ mov(r2, Operand(instr->name())); | 2920 __ mov(r2, Operand(instr->name())); |
| 2924 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 2921 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 2925 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2922 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 2926 : isolate()->builtins()->StoreIC_Initialize(); | 2923 : isolate()->builtins()->StoreIC_Initialize(); |
| 2927 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2924 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
| 2928 } | 2925 } |
| 2929 | 2926 |
| 2930 | 2927 |
| 2928 void LCodeGen::DoLinkObjectInList(LLinkObjectInList* instr) { |
| 2929 Register object = ToRegister(instr->object()); |
| 2930 ExternalReference sites_list_address = instr->GetReference(isolate()); |
| 2931 |
| 2932 __ mov(ip, Operand(sites_list_address)); |
| 2933 __ ldr(ip, MemOperand(ip)); |
| 2934 __ str(ip, FieldMemOperand(object, |
| 2935 instr->hydrogen()->store_field().offset())); |
| 2936 __ mov(ip, Operand(sites_list_address)); |
| 2937 __ str(object, MemOperand(ip)); |
| 2938 } |
| 2939 |
| 2940 |
| 2931 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2941 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2932 Register context = ToRegister(instr->context()); | 2942 Register context = ToRegister(instr->context()); |
| 2933 Register result = ToRegister(instr->result()); | 2943 Register result = ToRegister(instr->result()); |
| 2934 __ ldr(result, ContextOperand(context, instr->slot_index())); | 2944 __ ldr(result, ContextOperand(context, instr->slot_index())); |
| 2935 if (instr->hydrogen()->RequiresHoleCheck()) { | 2945 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2936 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 2946 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); |
| 2937 __ cmp(result, ip); | 2947 __ cmp(result, ip); |
| 2938 if (instr->hydrogen()->DeoptimizesOnHole()) { | 2948 if (instr->hydrogen()->DeoptimizesOnHole()) { |
| 2939 DeoptimizeIf(eq, instr->environment()); | 2949 DeoptimizeIf(eq, instr->environment()); |
| 2940 } else { | 2950 } else { |
| (...skipping 1570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4511 } else { | 4521 } else { |
| 4512 UNREACHABLE(); | 4522 UNREACHABLE(); |
| 4513 } | 4523 } |
| 4514 __ bind(¬_applicable); | 4524 __ bind(¬_applicable); |
| 4515 } | 4525 } |
| 4516 | 4526 |
| 4517 | 4527 |
| 4518 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 4528 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
| 4519 Register object = ToRegister(instr->object()); | 4529 Register object = ToRegister(instr->object()); |
| 4520 Register temp = ToRegister(instr->temp()); | 4530 Register temp = ToRegister(instr->temp()); |
| 4521 __ TestJSArrayForAllocationSiteInfo(object, temp); | 4531 __ TestJSArrayForAllocationMemento(object, temp); |
| 4522 DeoptimizeIf(eq, instr->environment()); | 4532 DeoptimizeIf(eq, instr->environment()); |
| 4523 } | 4533 } |
| 4524 | 4534 |
| 4525 | 4535 |
| 4526 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4536 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 4527 __ push(ToRegister(instr->left())); | 4537 __ push(ToRegister(instr->left())); |
| 4528 __ push(ToRegister(instr->right())); | 4538 __ push(ToRegister(instr->right())); |
| 4529 StringAddStub stub(NO_STRING_CHECK_IN_STUB); | 4539 StringAddStub stub(instr->hydrogen()->flags()); |
| 4530 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4540 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4531 } | 4541 } |
| 4532 | 4542 |
| 4533 | 4543 |
| 4534 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4544 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
| 4535 class DeferredStringCharCodeAt: public LDeferredCode { | 4545 class DeferredStringCharCodeAt: public LDeferredCode { |
| 4536 public: | 4546 public: |
| 4537 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4547 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
| 4538 : LDeferredCode(codegen), instr_(instr) { } | 4548 : LDeferredCode(codegen), instr_(instr) { } |
| 4539 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } | 4549 virtual void Generate() { codegen()->DoDeferredStringCharCodeAt(instr_); } |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5349 Register size = ToRegister(instr->size()); | 5359 Register size = ToRegister(instr->size()); |
| 5350 __ Allocate(size, | 5360 __ Allocate(size, |
| 5351 result, | 5361 result, |
| 5352 scratch, | 5362 scratch, |
| 5353 scratch2, | 5363 scratch2, |
| 5354 deferred->entry(), | 5364 deferred->entry(), |
| 5355 flags); | 5365 flags); |
| 5356 } | 5366 } |
| 5357 | 5367 |
| 5358 __ bind(deferred->exit()); | 5368 __ bind(deferred->exit()); |
| 5369 |
| 5370 if (instr->hydrogen()->MustPrefillWithFiller()) { |
| 5371 if (instr->size()->IsConstantOperand()) { |
| 5372 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 5373 __ mov(scratch, Operand(size)); |
| 5374 } else { |
| 5375 scratch = ToRegister(instr->size()); |
| 5376 } |
| 5377 __ sub(scratch, scratch, Operand(kPointerSize)); |
| 5378 __ sub(result, result, Operand(kHeapObjectTag)); |
| 5379 Label loop; |
| 5380 __ bind(&loop); |
| 5381 __ mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); |
| 5382 __ str(scratch2, MemOperand(result, scratch)); |
| 5383 __ sub(scratch, scratch, Operand(kPointerSize)); |
| 5384 __ cmp(scratch, Operand(0)); |
| 5385 __ b(ge, &loop); |
| 5386 __ add(result, result, Operand(kHeapObjectTag)); |
| 5387 } |
| 5359 } | 5388 } |
| 5360 | 5389 |
| 5361 | 5390 |
| 5362 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { | 5391 void LCodeGen::DoDeferredAllocate(LAllocate* instr) { |
| 5363 Register result = ToRegister(instr->result()); | 5392 Register result = ToRegister(instr->result()); |
| 5364 | 5393 |
| 5365 // TODO(3095996): Get rid of this. For now, we need to make the | 5394 // TODO(3095996): Get rid of this. For now, we need to make the |
| 5366 // result register contain a valid pointer because it is already | 5395 // result register contain a valid pointer because it is already |
| 5367 // contained in the register pointer map. | 5396 // contained in the register pointer map. |
| 5368 __ mov(result, Operand(Smi::FromInt(0))); | 5397 __ mov(result, Operand(Smi::FromInt(0))); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5595 if (current_pc < last_lazy_deopt_pc_ + patch_size) { | 5624 if (current_pc < last_lazy_deopt_pc_ + patch_size) { |
| 5596 // Block literal pool emission for duration of padding. | 5625 // Block literal pool emission for duration of padding. |
| 5597 Assembler::BlockConstPoolScope block_const_pool(masm()); | 5626 Assembler::BlockConstPoolScope block_const_pool(masm()); |
| 5598 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; | 5627 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; |
| 5599 ASSERT_EQ(0, padding_size % Assembler::kInstrSize); | 5628 ASSERT_EQ(0, padding_size % Assembler::kInstrSize); |
| 5600 while (padding_size > 0) { | 5629 while (padding_size > 0) { |
| 5601 __ nop(); | 5630 __ nop(); |
| 5602 padding_size -= Assembler::kInstrSize; | 5631 padding_size -= Assembler::kInstrSize; |
| 5603 } | 5632 } |
| 5604 } | 5633 } |
| 5605 last_lazy_deopt_pc_ = masm()->pc_offset(); | |
| 5606 } | 5634 } |
| 5607 | 5635 |
| 5608 | 5636 |
| 5609 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { | 5637 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { |
| 5610 EnsureSpaceForLazyDeopt(); | 5638 EnsureSpaceForLazyDeopt(); |
| 5639 last_lazy_deopt_pc_ = masm()->pc_offset(); |
| 5611 ASSERT(instr->HasEnvironment()); | 5640 ASSERT(instr->HasEnvironment()); |
| 5612 LEnvironment* env = instr->environment(); | 5641 LEnvironment* env = instr->environment(); |
| 5613 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); | 5642 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); |
| 5614 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 5643 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
| 5615 } | 5644 } |
| 5616 | 5645 |
| 5617 | 5646 |
| 5618 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { | 5647 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { |
| 5619 if (instr->hydrogen_value()->IsSoftDeoptimize()) { | 5648 if (instr->hydrogen_value()->IsSoftDeoptimize()) { |
| 5620 SoftDeoptimize(instr->environment()); | 5649 SoftDeoptimize(instr->environment()); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5658 if (instr->hydrogen()->is_function_entry()) { | 5687 if (instr->hydrogen()->is_function_entry()) { |
| 5659 // Perform stack overflow check. | 5688 // Perform stack overflow check. |
| 5660 Label done; | 5689 Label done; |
| 5661 __ LoadRoot(ip, Heap::kStackLimitRootIndex); | 5690 __ LoadRoot(ip, Heap::kStackLimitRootIndex); |
| 5662 __ cmp(sp, Operand(ip)); | 5691 __ cmp(sp, Operand(ip)); |
| 5663 __ b(hs, &done); | 5692 __ b(hs, &done); |
| 5664 StackCheckStub stub; | 5693 StackCheckStub stub; |
| 5665 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); | 5694 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); |
| 5666 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5695 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 5667 EnsureSpaceForLazyDeopt(); | 5696 EnsureSpaceForLazyDeopt(); |
| 5697 last_lazy_deopt_pc_ = masm()->pc_offset(); |
| 5668 __ bind(&done); | 5698 __ bind(&done); |
| 5669 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); | 5699 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); |
| 5670 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 5700 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
| 5671 } else { | 5701 } else { |
| 5672 ASSERT(instr->hydrogen()->is_backwards_branch()); | 5702 ASSERT(instr->hydrogen()->is_backwards_branch()); |
| 5673 // Perform stack overflow check if this goto needs it before jumping. | 5703 // Perform stack overflow check if this goto needs it before jumping. |
| 5674 DeferredStackCheck* deferred_stack_check = | 5704 DeferredStackCheck* deferred_stack_check = |
| 5675 new(zone()) DeferredStackCheck(this, instr); | 5705 new(zone()) DeferredStackCheck(this, instr); |
| 5676 __ LoadRoot(ip, Heap::kStackLimitRootIndex); | 5706 __ LoadRoot(ip, Heap::kStackLimitRootIndex); |
| 5677 __ cmp(sp, Operand(ip)); | 5707 __ cmp(sp, Operand(ip)); |
| 5678 __ b(lo, deferred_stack_check->entry()); | 5708 __ b(lo, deferred_stack_check->entry()); |
| 5679 EnsureSpaceForLazyDeopt(); | 5709 EnsureSpaceForLazyDeopt(); |
| 5710 last_lazy_deopt_pc_ = masm()->pc_offset(); |
| 5680 __ bind(instr->done_label()); | 5711 __ bind(instr->done_label()); |
| 5681 deferred_stack_check->SetExit(instr->done_label()); | 5712 deferred_stack_check->SetExit(instr->done_label()); |
| 5682 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); | 5713 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); |
| 5683 // Don't record a deoptimization index for the safepoint here. | 5714 // Don't record a deoptimization index for the safepoint here. |
| 5684 // This will be done explicitly when emitting call and the safepoint in | 5715 // This will be done explicitly when emitting call and the safepoint in |
| 5685 // the deferred code. | 5716 // the deferred code. |
| 5686 } | 5717 } |
| 5687 } | 5718 } |
| 5688 | 5719 |
| 5689 | 5720 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5794 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5825 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5795 __ ldr(result, FieldMemOperand(scratch, | 5826 __ ldr(result, FieldMemOperand(scratch, |
| 5796 FixedArray::kHeaderSize - kPointerSize)); | 5827 FixedArray::kHeaderSize - kPointerSize)); |
| 5797 __ bind(&done); | 5828 __ bind(&done); |
| 5798 } | 5829 } |
| 5799 | 5830 |
| 5800 | 5831 |
| 5801 #undef __ | 5832 #undef __ |
| 5802 | 5833 |
| 5803 } } // namespace v8::internal | 5834 } } // namespace v8::internal |
| OLD | NEW |