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

Side by Side Diff: src/arm64/deoptimizer-arm64.cc

Issue 341863002: ARM64: Give LR to the allocator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/codegen.h" 7 #include "src/codegen.h"
8 #include "src/deoptimizer.h" 8 #include "src/deoptimizer.h"
9 #include "src/full-codegen.h" 9 #include "src/full-codegen.h"
10 #include "src/safepoint-table.h" 10 #include "src/safepoint-table.h"
11 11
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 16
17 int Deoptimizer::patch_size() { 17 int Deoptimizer::patch_size() {
18 // Size of the code used to patch lazy bailout points. 18 // Size of the code used to patch lazy bailout points.
19 // Patching is done by Deoptimizer::DeoptimizeFunction. 19 // Patching is done by Deoptimizer::DeoptimizeFunction.
20 return 4 * kInstructionSize; 20 return 5 * kInstructionSize;
21 } 21 }
22 22
23 23
24 24
25 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { 25 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
26 // Invalidate the relocation information, as it will become invalid by the 26 // Invalidate the relocation information, as it will become invalid by the
27 // code patching below, and is not needed any more. 27 // code patching below, and is not needed any more.
28 code->InvalidateRelocation(); 28 code->InvalidateRelocation();
29 29
30 // TODO(jkummerow): if (FLAG_zap_code_space), make the code object's 30 // TODO(jkummerow): if (FLAG_zap_code_space), make the code object's
(...skipping 10 matching lines...) Expand all
41 #endif 41 #endif
42 // For each LLazyBailout instruction insert a call to the corresponding 42 // For each LLazyBailout instruction insert a call to the corresponding
43 // deoptimization entry. 43 // deoptimization entry.
44 for (int i = 0; i < deopt_data->DeoptCount(); i++) { 44 for (int i = 0; i < deopt_data->DeoptCount(); i++) {
45 if (deopt_data->Pc(i)->value() == -1) continue; 45 if (deopt_data->Pc(i)->value() == -1) continue;
46 46
47 Address call_address = code_start_address + deopt_data->Pc(i)->value(); 47 Address call_address = code_start_address + deopt_data->Pc(i)->value();
48 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); 48 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY);
49 49
50 PatchingAssembler patcher(call_address, patch_size() / kInstructionSize); 50 PatchingAssembler patcher(call_address, patch_size() / kInstructionSize);
51 patcher.adr(ip1, 0);
51 patcher.ldr_pcrel(ip0, (2 * kInstructionSize) >> kLoadLiteralScaleLog2); 52 patcher.ldr_pcrel(ip0, (2 * kInstructionSize) >> kLoadLiteralScaleLog2);
52 patcher.blr(ip0); 53 patcher.blr(ip0);
ulan 2014/06/23 11:17:11 Did you mean br(ip0) here?
jbramley 2014/06/23 17:22:05 Yes! Thank you.
53 patcher.dc64(reinterpret_cast<intptr_t>(deopt_entry)); 54 patcher.dc64(reinterpret_cast<intptr_t>(deopt_entry));
54 55
55 ASSERT((prev_call_address == NULL) || 56 ASSERT((prev_call_address == NULL) ||
56 (call_address >= prev_call_address + patch_size())); 57 (call_address >= prev_call_address + patch_size()));
57 ASSERT(call_address + patch_size() <= code->instruction_end()); 58 ASSERT(call_address + patch_size() <= code->instruction_end());
58 #ifdef DEBUG 59 #ifdef DEBUG
59 prev_call_address = call_address; 60 prev_call_address = call_address;
60 #endif 61 #endif
61 } 62 }
62 } 63 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset; 144 offset0 = (copy_to_input.PopLowestIndex().code() * reg_size) + dst_offset;
144 __ Str(scratch1, MemOperand(frame, offset0)); 145 __ Str(scratch1, MemOperand(frame, offset0));
145 } 146 }
146 } 147 }
147 148
148 #undef __ 149 #undef __
149 150
150 #define __ masm()-> 151 #define __ masm()->
151 152
152 void Deoptimizer::EntryGenerator::Generate() { 153 void Deoptimizer::EntryGenerator::Generate() {
154 UseScratchRegisterScope temps(masm());
155
156 // The deopt entry jump must put the caller address in ip1. This can be done
157 // either in the level-one deopt table (GenerateDeoptJumpTable), or inline in
158 // the code (DeoptimizeBranch).
159 Register caller_address = temps.Acquire(ip1);
160
153 GeneratePrologue(); 161 GeneratePrologue();
154 162
155 // TODO(all): This code needs to be revisited. We probably only need to save 163 // TODO(all): This code needs to be revisited. We probably only need to save
156 // caller-saved registers here. Callee-saved registers can be stored directly 164 // caller-saved registers here. Callee-saved registers can be stored directly
157 // in the input frame. 165 // in the input frame.
158 166
159 // Save all allocatable floating point registers. 167 // Save all allocatable floating point registers.
160 CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSizeInBits, 168 CPURegList saved_fp_registers(CPURegister::kFPRegister, kDRegSizeInBits,
161 FPRegister::kAllocatableFPRegisters); 169 FPRegister::kAllocatableFPRegisters);
162 __ PushCPURegList(saved_fp_registers); 170 __ PushCPURegList(saved_fp_registers);
163 171
164 // We save all the registers expcept jssp, sp and lr. 172 // We save all allocatable registers plus fp.
165 CPURegList saved_registers(CPURegister::kRegister, kXRegSizeInBits, 0, 27); 173 CPURegList saved_registers(CPURegister::kRegister, kXRegSizeInBits,
166 saved_registers.Combine(fp); 174 Register::kAllocatableRegisters | fp.Bit());
167 __ PushCPURegList(saved_registers); 175 __ PushCPURegList(saved_registers);
168 176
169 const int kSavedRegistersAreaSize = 177 const int kSavedRegistersAreaSize =
170 (saved_registers.Count() * kXRegSize) + 178 (saved_registers.Count() * kXRegSize) +
171 (saved_fp_registers.Count() * kDRegSize); 179 (saved_fp_registers.Count() * kDRegSize);
172 180
173 // Floating point registers are saved on the stack above core registers. 181 // Floating point registers are saved on the stack above core registers.
174 const int kFPRegistersOffset = saved_registers.Count() * kXRegSize; 182 const int kFPRegistersOffset = saved_registers.Count() * kXRegSize;
175 183
176 // Get the bailout id from the stack. 184 // Get the bailout id from the stack.
177 Register bailout_id = x2; 185 Register bailout_id = x2;
178 __ Peek(bailout_id, kSavedRegistersAreaSize); 186 __ Peek(bailout_id, kSavedRegistersAreaSize);
179 187
180 Register code_object = x3; 188 Register code_object = x3;
181 Register fp_to_sp = x4; 189 Register fp_to_sp = x4;
182 // Get the address of the location in the code object. This is the return 190 // Get the address of the location in the code object. This is the return
183 // address for lazy deoptimization. 191 // address for lazy deoptimization.
184 __ Mov(code_object, lr); 192 __ Mov(code_object, caller_address);
185 // Compute the fp-to-sp delta, and correct one word for bailout id. 193 // Compute the fp-to-sp delta, and correct one word for bailout id.
186 __ Add(fp_to_sp, masm()->StackPointer(), 194 __ Add(fp_to_sp, masm()->StackPointer(),
187 kSavedRegistersAreaSize + (1 * kPointerSize)); 195 kSavedRegistersAreaSize + (1 * kPointerSize));
188 __ Sub(fp_to_sp, fp, fp_to_sp); 196 __ Sub(fp_to_sp, fp, fp_to_sp);
189 197
190 // Allocate a new deoptimizer object. 198 // Allocate a new deoptimizer object.
191 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 199 __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
192 __ Mov(x1, type()); 200 __ Mov(x1, type());
193 // Following arguments are already loaded: 201 // Following arguments are already loaded:
194 // - x2: bailout id 202 // - x2: bailout id
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 // TODO(all): ARM copies a lot (if not all) of the last output frame onto the 304 // TODO(all): ARM copies a lot (if not all) of the last output frame onto the
297 // stack, then pops it all into registers. Here, we try to load it directly 305 // stack, then pops it all into registers. Here, we try to load it directly
298 // into the relevant registers. Is this correct? If so, we should improve the 306 // into the relevant registers. Is this correct? If so, we should improve the
299 // ARM code. 307 // ARM code.
300 308
301 // TODO(all): This code needs to be revisited, We probably don't need to 309 // TODO(all): This code needs to be revisited, We probably don't need to
302 // restore all the registers as fullcodegen does not keep live values in 310 // restore all the registers as fullcodegen does not keep live values in
303 // registers (note that at least fp must be restored though). 311 // registers (note that at least fp must be restored though).
304 312
305 // Restore registers from the last output frame. 313 // Restore registers from the last output frame.
306 // Note that lr is not in the list of saved_registers and will be restored 314 Register last_output_frame = temps.AcquireX();
307 // later. We can use it to hold the address of last output frame while 315 ASSERT(!saved_registers.IncludesAliasOf(last_output_frame));
308 // reloading the other registers.
309 ASSERT(!saved_registers.IncludesAliasOf(lr));
310 Register last_output_frame = lr;
311 __ Mov(last_output_frame, current_frame); 316 __ Mov(last_output_frame, current_frame);
312 317
313 // We don't need to restore x7 as it will be clobbered later to hold the 318 // We don't need to restore x7 as it will be clobbered later to hold the
314 // continuation address. 319 // continuation address.
315 Register continuation = x7; 320 Register continuation = x7;
316 saved_registers.Remove(continuation); 321 saved_registers.Remove(continuation);
317 322
318 while (!saved_registers.IsEmpty()) { 323 while (!saved_registers.IsEmpty()) {
319 // TODO(all): Look for opportunities to optimize this by using ldp. 324 // TODO(all): Look for opportunities to optimize this by using ldp.
320 CPURegister current_reg = saved_registers.PopLowestIndex(); 325 CPURegister current_reg = saved_registers.PopLowestIndex();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 381
377 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { 382 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
378 // No out-of-line constant pool support. 383 // No out-of-line constant pool support.
379 UNREACHABLE(); 384 UNREACHABLE();
380 } 385 }
381 386
382 387
383 #undef __ 388 #undef __
384 389
385 } } // namespace v8::internal 390 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698