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

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

Issue 145773008: A64: Synchronize with r17104. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.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 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 info()->CommitDependencies(code); 91 info()->CommitDependencies(code);
92 } 92 }
93 93
94 94
95 void LCodeGen::Abort(BailoutReason reason) { 95 void LCodeGen::Abort(BailoutReason reason) {
96 info()->set_bailout_reason(reason); 96 info()->set_bailout_reason(reason);
97 status_ = ABORTED; 97 status_ = ABORTED;
98 } 98 }
99 99
100 100
101 void LCodeGen::Comment(const char* format, ...) {
102 if (!FLAG_code_comments) return;
103 char buffer[4 * KB];
104 StringBuilder builder(buffer, ARRAY_SIZE(buffer));
105 va_list arguments;
106 va_start(arguments, format);
107 builder.AddFormattedList(format, arguments);
108 va_end(arguments);
109
110 // Copy the string before recording it in the assembler to avoid
111 // issues when the stack allocated buffer goes out of scope.
112 size_t length = builder.position();
113 Vector<char> copy = Vector<char>::New(length + 1);
114 OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
115 masm()->RecordComment(copy.start());
116 }
117
118
119 bool LCodeGen::GeneratePrologue() { 101 bool LCodeGen::GeneratePrologue() {
120 ASSERT(is_generating()); 102 ASSERT(is_generating());
121 103
122 if (info()->IsOptimizing()) { 104 if (info()->IsOptimizing()) {
123 ProfileEntryHookStub::MaybeCallEntryHook(masm_); 105 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
124 106
125 #ifdef DEBUG 107 #ifdef DEBUG
126 if (strlen(FLAG_stop_at) > 0 && 108 if (strlen(FLAG_stop_at) > 0 &&
127 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 109 info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
128 __ stop("stop_at"); 110 __ stop("stop_at");
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 osr_pc_offset_ = masm()->pc_offset(); 246 osr_pc_offset_ = masm()->pc_offset();
265 247
266 // Adjust the frame size, subsuming the unoptimized frame into the 248 // Adjust the frame size, subsuming the unoptimized frame into the
267 // optimized frame. 249 // optimized frame.
268 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); 250 int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
269 ASSERT(slots >= 0); 251 ASSERT(slots >= 0);
270 __ sub(sp, sp, Operand(slots * kPointerSize)); 252 __ sub(sp, sp, Operand(slots * kPointerSize));
271 } 253 }
272 254
273 255
274 bool LCodeGen::GenerateBody() {
275 ASSERT(is_generating());
276 bool emit_instructions = true;
277 for (current_instruction_ = 0;
278 !is_aborted() && current_instruction_ < instructions_->length();
279 current_instruction_++) {
280 LInstruction* instr = instructions_->at(current_instruction_);
281
282 // Don't emit code for basic blocks with a replacement.
283 if (instr->IsLabel()) {
284 emit_instructions = !LLabel::cast(instr)->HasReplacement();
285 }
286 if (!emit_instructions) continue;
287
288 if (FLAG_code_comments && instr->HasInterestingComment(this)) {
289 Comment(";;; <@%d,#%d> %s",
290 current_instruction_,
291 instr->hydrogen_value()->id(),
292 instr->Mnemonic());
293 }
294
295 RecordAndUpdatePosition(instr->position());
296
297 instr->CompileToNative(this);
298 }
299 EnsureSpaceForLazyDeopt();
300 last_lazy_deopt_pc_ = masm()->pc_offset();
301 return !is_aborted();
302 }
303
304
305 bool LCodeGen::GenerateDeferredCode() { 256 bool LCodeGen::GenerateDeferredCode() {
306 ASSERT(is_generating()); 257 ASSERT(is_generating());
307 if (deferred_.length() > 0) { 258 if (deferred_.length() > 0) {
308 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 259 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
309 LDeferredCode* code = deferred_[i]; 260 LDeferredCode* code = deferred_[i];
310 261
311 int pos = instructions_->at(code->instruction_index())->position(); 262 int pos = instructions_->at(code->instruction_index())->position();
312 RecordAndUpdatePosition(pos); 263 RecordAndUpdatePosition(pos);
313 264
314 Comment(";;; <@%d,#%d> " 265 Comment(";;; <@%d,#%d> "
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 TargetAddressStorageMode storage_mode) { 673 TargetAddressStorageMode storage_mode) {
723 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode); 674 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT, storage_mode);
724 } 675 }
725 676
726 677
727 void LCodeGen::CallCodeGeneric(Handle<Code> code, 678 void LCodeGen::CallCodeGeneric(Handle<Code> code,
728 RelocInfo::Mode mode, 679 RelocInfo::Mode mode,
729 LInstruction* instr, 680 LInstruction* instr,
730 SafepointMode safepoint_mode, 681 SafepointMode safepoint_mode,
731 TargetAddressStorageMode storage_mode) { 682 TargetAddressStorageMode storage_mode) {
732 EnsureSpaceForLazyDeopt(); 683 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
733 ASSERT(instr != NULL); 684 ASSERT(instr != NULL);
734 // Block literal pool emission to ensure nop indicating no inlined smi code 685 // Block literal pool emission to ensure nop indicating no inlined smi code
735 // is in the correct position. 686 // is in the correct position.
736 Assembler::BlockConstPoolScope block_const_pool(masm()); 687 Assembler::BlockConstPoolScope block_const_pool(masm());
737 LPointerMap* pointers = instr->pointer_map(); 688 LPointerMap* pointers = instr->pointer_map();
738 RecordPosition(pointers->position()); 689 RecordPosition(pointers->position());
739 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); 690 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode);
740 RecordSafepointWithLazyDeopt(instr, safepoint_mode); 691 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
741 692
742 // Signal that we don't inline smi code before these stubs in the 693 // Signal that we don't inline smi code before these stubs in the
743 // optimizing code generator. 694 // optimizing code generator.
744 if (code->kind() == Code::BINARY_OP_IC || 695 if (code->kind() == Code::BINARY_OP_IC ||
745 code->kind() == Code::COMPARE_IC) { 696 code->kind() == Code::COMPARE_IC) {
746 __ nop(); 697 __ nop();
747 } 698 }
748 } 699 }
749 700
750 701
751 void LCodeGen::CallRuntime(const Runtime::Function* function, 702 void LCodeGen::CallRuntime(const Runtime::Function* function,
752 int num_arguments, 703 int num_arguments,
753 LInstruction* instr) { 704 LInstruction* instr,
705 SaveFPRegsMode save_doubles) {
754 ASSERT(instr != NULL); 706 ASSERT(instr != NULL);
755 LPointerMap* pointers = instr->pointer_map(); 707 LPointerMap* pointers = instr->pointer_map();
756 ASSERT(pointers != NULL); 708 ASSERT(pointers != NULL);
757 RecordPosition(pointers->position()); 709 RecordPosition(pointers->position());
758 710
759 __ CallRuntime(function, num_arguments); 711 __ CallRuntime(function, num_arguments, save_doubles);
712
760 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); 713 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
761 } 714 }
762 715
763 716
764 void LCodeGen::LoadContextFromDeferred(LOperand* context) { 717 void LCodeGen::LoadContextFromDeferred(LOperand* context) {
765 if (context->IsRegister()) { 718 if (context->IsRegister()) {
766 __ Move(cp, ToRegister(context)); 719 __ Move(cp, ToRegister(context));
767 } else if (context->IsStackSlot()) { 720 } else if (context->IsStackSlot()) {
768 __ ldr(cp, ToMemOperand(context)); 721 __ ldr(cp, ToMemOperand(context));
722 } else if (context->IsConstantOperand()) {
723 HConstant* constant =
724 chunk_->LookupConstant(LConstantOperand::cast(context));
725 __ LoadObject(cp, Handle<Object>::cast(constant->handle(isolate())));
769 } else { 726 } else {
770 UNREACHABLE(); 727 UNREACHABLE();
771 } 728 }
772 } 729 }
773 730
774 731
775 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 732 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
776 int argc, 733 int argc,
777 LInstruction* instr, 734 LInstruction* instr,
778 LOperand* context) { 735 LOperand* context) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 LEnvironment* environment) { 827 LEnvironment* environment) {
871 Deoptimizer::BailoutType bailout_type = info()->IsStub() 828 Deoptimizer::BailoutType bailout_type = info()->IsStub()
872 ? Deoptimizer::LAZY 829 ? Deoptimizer::LAZY
873 : Deoptimizer::EAGER; 830 : Deoptimizer::EAGER;
874 DeoptimizeIf(condition, environment, bailout_type); 831 DeoptimizeIf(condition, environment, bailout_type);
875 } 832 }
876 833
877 834
878 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) { 835 void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
879 ZoneList<Handle<Map> > maps(1, zone()); 836 ZoneList<Handle<Map> > maps(1, zone());
837 ZoneList<Handle<JSObject> > objects(1, zone());
880 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 838 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
881 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) { 839 for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
882 RelocInfo::Mode mode = it.rinfo()->rmode(); 840 if (Code::IsWeakEmbeddedObject(code->kind(), it.rinfo()->target_object())) {
883 if (mode == RelocInfo::EMBEDDED_OBJECT && 841 if (it.rinfo()->target_object()->IsMap()) {
884 it.rinfo()->target_object()->IsMap()) { 842 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
885 Handle<Map> map(Map::cast(it.rinfo()->target_object()));
886 if (map->CanTransition()) {
887 maps.Add(map, zone()); 843 maps.Add(map, zone());
844 } else if (it.rinfo()->target_object()->IsJSObject()) {
845 Handle<JSObject> object(JSObject::cast(it.rinfo()->target_object()));
846 objects.Add(object, zone());
888 } 847 }
889 } 848 }
890 } 849 }
891 #ifdef VERIFY_HEAP 850 #ifdef VERIFY_HEAP
892 // This disables verification of weak embedded maps after full GC. 851 // This disables verification of weak embedded objects after full GC.
893 // AddDependentCode can cause a GC, which would observe the state where 852 // AddDependentCode can cause a GC, which would observe the state where
894 // this code is not yet in the depended code lists of the embedded maps. 853 // this code is not yet in the depended code lists of the embedded maps.
895 NoWeakEmbeddedMapsVerificationScope disable_verification_of_embedded_maps; 854 NoWeakObjectVerificationScope disable_verification_of_embedded_objects;
896 #endif 855 #endif
897 for (int i = 0; i < maps.length(); i++) { 856 for (int i = 0; i < maps.length(); i++) {
898 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code); 857 maps.at(i)->AddDependentCode(DependentCode::kWeaklyEmbeddedGroup, code);
899 } 858 }
859 for (int i = 0; i < objects.length(); i++) {
860 AddWeakObjectToCodeDependency(isolate()->heap(), objects.at(i), code);
861 }
900 } 862 }
901 863
902 864
903 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 865 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
904 int length = deoptimizations_.length(); 866 int length = deoptimizations_.length();
905 if (length == 0) return; 867 if (length == 0) return;
906 Handle<DeoptimizationInputData> data = 868 Handle<DeoptimizationInputData> data =
907 factory()->NewDeoptimizationInputData(length, TENURED); 869 factory()->NewDeoptimizationInputData(length, TENURED);
908 870
909 Handle<ByteArray> translations = 871 Handle<ByteArray> translations =
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after
2180 2142
2181 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 2143 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
2182 // Block literal pool emission to ensure nop indicating no inlined smi code 2144 // Block literal pool emission to ensure nop indicating no inlined smi code
2183 // is in the correct position. 2145 // is in the correct position.
2184 Assembler::BlockConstPoolScope block_const_pool(masm()); 2146 Assembler::BlockConstPoolScope block_const_pool(masm());
2185 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 2147 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
2186 __ nop(); // Signals no inlined code. 2148 __ nop(); // Signals no inlined code.
2187 } 2149 }
2188 2150
2189 2151
2190 int LCodeGen::GetNextEmittedBlock() const {
2191 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
2192 if (!chunk_->GetLabel(i)->HasReplacement()) return i;
2193 }
2194 return -1;
2195 }
2196
2197 template<class InstrType> 2152 template<class InstrType>
2198 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { 2153 void LCodeGen::EmitBranch(InstrType instr, Condition condition) {
2199 int left_block = instr->TrueDestination(chunk_); 2154 int left_block = instr->TrueDestination(chunk_);
2200 int right_block = instr->FalseDestination(chunk_); 2155 int right_block = instr->FalseDestination(chunk_);
2201 2156
2202 int next_block = GetNextEmittedBlock(); 2157 int next_block = GetNextEmittedBlock();
2203 2158
2204 if (right_block == left_block || condition == al) { 2159 if (right_block == left_block || condition == al) {
2205 EmitGoto(left_block); 2160 EmitGoto(left_block);
2206 } else if (left_block == next_block) { 2161 } else if (left_block == next_block) {
(...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after
3085 } 3040 }
3086 3041
3087 3042
3088 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3043 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
3089 HObjectAccess access = instr->hydrogen()->access(); 3044 HObjectAccess access = instr->hydrogen()->access();
3090 int offset = access.offset(); 3045 int offset = access.offset();
3091 Register object = ToRegister(instr->object()); 3046 Register object = ToRegister(instr->object());
3092 3047
3093 if (access.IsExternalMemory()) { 3048 if (access.IsExternalMemory()) {
3094 Register result = ToRegister(instr->result()); 3049 Register result = ToRegister(instr->result());
3095 __ ldr(result, MemOperand(object, offset)); 3050 MemOperand operand = MemOperand(object, offset);
3051 if (access.representation().IsByte()) {
3052 __ ldrb(result, operand);
3053 } else {
3054 __ ldr(result, operand);
3055 }
3096 return; 3056 return;
3097 } 3057 }
3098 3058
3099 if (instr->hydrogen()->representation().IsDouble()) { 3059 if (instr->hydrogen()->representation().IsDouble()) {
3100 DwVfpRegister result = ToDoubleRegister(instr->result()); 3060 DwVfpRegister result = ToDoubleRegister(instr->result());
3101 __ vldr(result, FieldMemOperand(object, offset)); 3061 __ vldr(result, FieldMemOperand(object, offset));
3102 return; 3062 return;
3103 } 3063 }
3104 3064
3105 Register result = ToRegister(instr->result()); 3065 Register result = ToRegister(instr->result());
3106 if (access.IsInobject()) { 3066 if (!access.IsInobject()) {
3107 __ ldr(result, FieldMemOperand(object, offset)); 3067 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
3068 object = result;
3069 }
3070 MemOperand operand = FieldMemOperand(object, offset);
3071 if (access.representation().IsByte()) {
3072 __ ldrb(result, operand);
3108 } else { 3073 } else {
3109 __ ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); 3074 __ ldr(result, operand);
3110 __ ldr(result, FieldMemOperand(result, offset));
3111 } 3075 }
3112 } 3076 }
3113 3077
3114 3078
3115 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { 3079 void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
3116 ASSERT(ToRegister(instr->context()).is(cp)); 3080 ASSERT(ToRegister(instr->context()).is(cp));
3117 ASSERT(ToRegister(instr->object()).is(r0)); 3081 ASSERT(ToRegister(instr->object()).is(r0));
3118 ASSERT(ToRegister(instr->result()).is(r0)); 3082 ASSERT(ToRegister(instr->result()).is(r0));
3119 3083
3120 // Name is always in r2. 3084 // Name is always in r2.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
3284 3248
3285 3249
3286 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) { 3250 void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
3287 Register elements = ToRegister(instr->elements()); 3251 Register elements = ToRegister(instr->elements());
3288 bool key_is_constant = instr->key()->IsConstantOperand(); 3252 bool key_is_constant = instr->key()->IsConstantOperand();
3289 Register key = no_reg; 3253 Register key = no_reg;
3290 DwVfpRegister result = ToDoubleRegister(instr->result()); 3254 DwVfpRegister result = ToDoubleRegister(instr->result());
3291 Register scratch = scratch0(); 3255 Register scratch = scratch0();
3292 3256
3293 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 3257 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
3294 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) 3258
3295 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3259 int base_offset =
3296 int constant_key = 0; 3260 FixedDoubleArray::kHeaderSize - kHeapObjectTag +
3261 (instr->additional_index() << element_size_shift);
3297 if (key_is_constant) { 3262 if (key_is_constant) {
3298 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3263 int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3299 if (constant_key & 0xF0000000) { 3264 if (constant_key & 0xF0000000) {
3300 Abort(kArrayIndexConstantValueTooBig); 3265 Abort(kArrayIndexConstantValueTooBig);
3301 } 3266 }
3302 } else { 3267 base_offset += constant_key << element_size_shift;
3268 }
3269 __ add(scratch, elements, Operand(base_offset));
3270
3271 if (!key_is_constant) {
3303 key = ToRegister(instr->key()); 3272 key = ToRegister(instr->key());
3273 int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
3274 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3275 __ add(scratch, scratch, Operand(key, LSL, shift_size));
3304 } 3276 }
3305 3277
3306 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + 3278 __ vldr(result, scratch, 0);
3307 ((constant_key + instr->additional_index()) << element_size_shift); 3279
3308 if (!key_is_constant) {
3309 __ add(elements, elements, Operand(key, LSL, shift_size));
3310 }
3311 __ add(elements, elements, Operand(base_offset));
3312 __ vldr(result, elements, 0);
3313 if (instr->hydrogen()->RequiresHoleCheck()) { 3280 if (instr->hydrogen()->RequiresHoleCheck()) {
3314 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 3281 __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32)));
3315 __ cmp(scratch, Operand(kHoleNanUpper32)); 3282 __ cmp(scratch, Operand(kHoleNanUpper32));
3316 DeoptimizeIf(eq, instr->environment()); 3283 DeoptimizeIf(eq, instr->environment());
3317 } 3284 }
3318 } 3285 }
3319 3286
3320 3287
3321 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3288 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3322 Register elements = ToRegister(instr->elements()); 3289 Register elements = ToRegister(instr->elements());
3323 Register result = ToRegister(instr->result()); 3290 Register result = ToRegister(instr->result());
3324 Register scratch = scratch0(); 3291 Register scratch = scratch0();
3325 Register store_base = scratch; 3292 Register store_base = scratch;
3326 int offset = 0; 3293 int offset = 0;
3327 3294
3328 if (instr->key()->IsConstantOperand()) { 3295 if (instr->key()->IsConstantOperand()) {
3329 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3296 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3330 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) + 3297 offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
3331 instr->additional_index()); 3298 instr->additional_index());
3332 store_base = elements; 3299 store_base = elements;
3333 } else { 3300 } else {
3334 Register key = EmitLoadRegister(instr->key(), scratch0()); 3301 Register key = ToRegister(instr->key());
3335 // Even though the HLoadKeyed instruction forces the input 3302 // Even though the HLoadKeyed instruction forces the input
3336 // representation for the key to be an integer, the input gets replaced 3303 // representation for the key to be an integer, the input gets replaced
3337 // during bound check elimination with the index argument to the bounds 3304 // during bound check elimination with the index argument to the bounds
3338 // check, which can be tagged, so that case must be handled here, too. 3305 // check, which can be tagged, so that case must be handled here, too.
3339 if (instr->hydrogen()->key()->representation().IsSmi()) { 3306 if (instr->hydrogen()->key()->representation().IsSmi()) {
3340 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key)); 3307 __ add(scratch, elements, Operand::PointerOffsetFromSmiKey(key));
3341 } else { 3308 } else {
3342 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 3309 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
3343 } 3310 }
3344 offset = FixedArray::OffsetOfElementAt(instr->additional_index()); 3311 offset = FixedArray::OffsetOfElementAt(instr->additional_index());
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
4203 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { 4170 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
4204 Representation representation = instr->representation(); 4171 Representation representation = instr->representation();
4205 4172
4206 Register object = ToRegister(instr->object()); 4173 Register object = ToRegister(instr->object());
4207 Register scratch = scratch0(); 4174 Register scratch = scratch0();
4208 HObjectAccess access = instr->hydrogen()->access(); 4175 HObjectAccess access = instr->hydrogen()->access();
4209 int offset = access.offset(); 4176 int offset = access.offset();
4210 4177
4211 if (access.IsExternalMemory()) { 4178 if (access.IsExternalMemory()) {
4212 Register value = ToRegister(instr->value()); 4179 Register value = ToRegister(instr->value());
4213 __ str(value, MemOperand(object, offset)); 4180 MemOperand operand = MemOperand(object, offset);
4181 if (representation.IsByte()) {
4182 __ strb(value, operand);
4183 } else {
4184 __ str(value, operand);
4185 }
4214 return; 4186 return;
4215 } 4187 }
4216 4188
4217 Handle<Map> transition = instr->transition(); 4189 Handle<Map> transition = instr->transition();
4218 4190
4219 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 4191 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
4220 Register value = ToRegister(instr->value()); 4192 Register value = ToRegister(instr->value());
4221 if (!instr->hydrogen()->value()->type().IsHeapObject()) { 4193 if (!instr->hydrogen()->value()->type().IsHeapObject()) {
4222 __ SmiTst(value); 4194 __ SmiTst(value);
4223 DeoptimizeIf(eq, instr->environment()); 4195 DeoptimizeIf(eq, instr->environment());
(...skipping 24 matching lines...) Expand all
4248 } 4220 }
4249 } 4221 }
4250 4222
4251 // Do the store. 4223 // Do the store.
4252 Register value = ToRegister(instr->value()); 4224 Register value = ToRegister(instr->value());
4253 ASSERT(!object.is(value)); 4225 ASSERT(!object.is(value));
4254 SmiCheck check_needed = 4226 SmiCheck check_needed =
4255 instr->hydrogen()->value()->IsHeapObject() 4227 instr->hydrogen()->value()->IsHeapObject()
4256 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 4228 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
4257 if (access.IsInobject()) { 4229 if (access.IsInobject()) {
4258 __ str(value, FieldMemOperand(object, offset)); 4230 MemOperand operand = FieldMemOperand(object, offset);
4231 if (representation.IsByte()) {
4232 __ strb(value, operand);
4233 } else {
4234 __ str(value, operand);
4235 }
4259 if (instr->hydrogen()->NeedsWriteBarrier()) { 4236 if (instr->hydrogen()->NeedsWriteBarrier()) {
4260 // Update the write barrier for the object for in-object properties. 4237 // Update the write barrier for the object for in-object properties.
4261 __ RecordWriteField(object, 4238 __ RecordWriteField(object,
4262 offset, 4239 offset,
4263 value, 4240 value,
4264 scratch, 4241 scratch,
4265 GetLinkRegisterState(), 4242 GetLinkRegisterState(),
4266 kSaveFPRegs, 4243 kSaveFPRegs,
4267 EMIT_REMEMBERED_SET, 4244 EMIT_REMEMBERED_SET,
4268 check_needed); 4245 check_needed);
4269 } 4246 }
4270 } else { 4247 } else {
4271 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset)); 4248 __ ldr(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
4272 __ str(value, FieldMemOperand(scratch, offset)); 4249 MemOperand operand = FieldMemOperand(scratch, offset);
4250 if (representation.IsByte()) {
4251 __ strb(value, operand);
4252 } else {
4253 __ str(value, operand);
4254 }
4273 if (instr->hydrogen()->NeedsWriteBarrier()) { 4255 if (instr->hydrogen()->NeedsWriteBarrier()) {
4274 // Update the write barrier for the properties array. 4256 // Update the write barrier for the properties array.
4275 // object is used as a scratch register. 4257 // object is used as a scratch register.
4276 __ RecordWriteField(scratch, 4258 __ RecordWriteField(scratch,
4277 offset, 4259 offset,
4278 value, 4260 value,
4279 object, 4261 object,
4280 GetLinkRegisterState(), 4262 GetLinkRegisterState(),
4281 kSaveFPRegs, 4263 kSaveFPRegs,
4282 EMIT_REMEMBERED_SET, 4264 EMIT_REMEMBERED_SET,
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after
5626 __ b(ne, &check_frame_marker); 5608 __ b(ne, &check_frame_marker);
5627 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset)); 5609 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
5628 5610
5629 // Check the marker in the calling frame. 5611 // Check the marker in the calling frame.
5630 __ bind(&check_frame_marker); 5612 __ bind(&check_frame_marker);
5631 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 5613 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
5632 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5614 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5633 } 5615 }
5634 5616
5635 5617
5636 void LCodeGen::EnsureSpaceForLazyDeopt() { 5618 void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
5637 if (info()->IsStub()) return; 5619 if (info()->IsStub()) return;
5638 // Ensure that we have enough space after the previous lazy-bailout 5620 // Ensure that we have enough space after the previous lazy-bailout
5639 // instruction for patching the code here. 5621 // instruction for patching the code here.
5640 int current_pc = masm()->pc_offset(); 5622 int current_pc = masm()->pc_offset();
5641 int patch_size = Deoptimizer::patch_size(); 5623 if (current_pc < last_lazy_deopt_pc_ + space_needed) {
5642 if (current_pc < last_lazy_deopt_pc_ + patch_size) {
5643 // Block literal pool emission for duration of padding. 5624 // Block literal pool emission for duration of padding.
5644 Assembler::BlockConstPoolScope block_const_pool(masm()); 5625 Assembler::BlockConstPoolScope block_const_pool(masm());
5645 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 5626 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
5646 ASSERT_EQ(0, padding_size % Assembler::kInstrSize); 5627 ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
5647 while (padding_size > 0) { 5628 while (padding_size > 0) {
5648 __ nop(); 5629 __ nop();
5649 padding_size -= Assembler::kInstrSize; 5630 padding_size -= Assembler::kInstrSize;
5650 } 5631 }
5651 } 5632 }
5652 } 5633 }
5653 5634
5654 5635
5655 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 5636 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
5656 EnsureSpaceForLazyDeopt(); 5637 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5657 last_lazy_deopt_pc_ = masm()->pc_offset(); 5638 last_lazy_deopt_pc_ = masm()->pc_offset();
5658 ASSERT(instr->HasEnvironment()); 5639 ASSERT(instr->HasEnvironment());
5659 LEnvironment* env = instr->environment(); 5640 LEnvironment* env = instr->environment();
5660 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5641 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5661 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5642 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5662 } 5643 }
5663 5644
5664 5645
5665 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 5646 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
5666 Deoptimizer::BailoutType type = instr->hydrogen()->type(); 5647 Deoptimizer::BailoutType type = instr->hydrogen()->type();
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
5716 Label done; 5697 Label done;
5717 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 5698 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
5718 __ cmp(sp, Operand(ip)); 5699 __ cmp(sp, Operand(ip));
5719 __ b(hs, &done); 5700 __ b(hs, &done);
5720 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize); 5701 PredictableCodeSizeScope predictable(masm_, 2 * Assembler::kInstrSize);
5721 ASSERT(instr->context()->IsRegister()); 5702 ASSERT(instr->context()->IsRegister());
5722 ASSERT(ToRegister(instr->context()).is(cp)); 5703 ASSERT(ToRegister(instr->context()).is(cp));
5723 CallCode(isolate()->builtins()->StackCheck(), 5704 CallCode(isolate()->builtins()->StackCheck(),
5724 RelocInfo::CODE_TARGET, 5705 RelocInfo::CODE_TARGET,
5725 instr); 5706 instr);
5726 EnsureSpaceForLazyDeopt(); 5707 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5727 last_lazy_deopt_pc_ = masm()->pc_offset(); 5708 last_lazy_deopt_pc_ = masm()->pc_offset();
5728 __ bind(&done); 5709 __ bind(&done);
5729 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5710 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5730 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); 5711 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
5731 } else { 5712 } else {
5732 ASSERT(instr->hydrogen()->is_backwards_branch()); 5713 ASSERT(instr->hydrogen()->is_backwards_branch());
5733 // Perform stack overflow check if this goto needs it before jumping. 5714 // Perform stack overflow check if this goto needs it before jumping.
5734 DeferredStackCheck* deferred_stack_check = 5715 DeferredStackCheck* deferred_stack_check =
5735 new(zone()) DeferredStackCheck(this, instr); 5716 new(zone()) DeferredStackCheck(this, instr);
5736 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 5717 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
5737 __ cmp(sp, Operand(ip)); 5718 __ cmp(sp, Operand(ip));
5738 __ b(lo, deferred_stack_check->entry()); 5719 __ b(lo, deferred_stack_check->entry());
5739 EnsureSpaceForLazyDeopt(); 5720 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
5740 last_lazy_deopt_pc_ = masm()->pc_offset(); 5721 last_lazy_deopt_pc_ = masm()->pc_offset();
5741 __ bind(instr->done_label()); 5722 __ bind(instr->done_label());
5742 deferred_stack_check->SetExit(instr->done_label()); 5723 deferred_stack_check->SetExit(instr->done_label());
5743 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); 5724 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
5744 // Don't record a deoptimization index for the safepoint here. 5725 // Don't record a deoptimization index for the safepoint here.
5745 // This will be done explicitly when emitting call and the safepoint in 5726 // This will be done explicitly when emitting call and the safepoint in
5746 // the deferred code. 5727 // the deferred code.
5747 } 5728 }
5748 } 5729 }
5749 5730
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
5853 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); 5834 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index));
5854 __ ldr(result, FieldMemOperand(scratch, 5835 __ ldr(result, FieldMemOperand(scratch,
5855 FixedArray::kHeaderSize - kPointerSize)); 5836 FixedArray::kHeaderSize - kPointerSize));
5856 __ bind(&done); 5837 __ bind(&done);
5857 } 5838 }
5858 5839
5859 5840
5860 #undef __ 5841 #undef __
5861 5842
5862 } } // namespace v8::internal 5843 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698