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

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

Issue 21340002: Generate a custom OSR entrypoint for OSR compiles on all platforms, and transition to optimized cod… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 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 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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 ASSERT_EQ(kBranchBeforeInterrupt, 173 ASSERT_EQ(kBranchBeforeInterrupt,
174 Memory::int32_at(pc_after - 3 * kInstrSize)); 174 Memory::int32_at(pc_after - 3 * kInstrSize));
175 ASSERT(reinterpret_cast<uint32_t>(interrupt_code->entry()) == 175 ASSERT(reinterpret_cast<uint32_t>(interrupt_code->entry()) ==
176 Memory::uint32_at(interrupt_address_pointer)); 176 Memory::uint32_at(interrupt_address_pointer));
177 return false; 177 return false;
178 } 178 }
179 } 179 }
180 #endif // DEBUG 180 #endif // DEBUG
181 181
182 182
183 static int LookupBailoutId(DeoptimizationInputData* data, BailoutId ast_id) {
184 ByteArray* translations = data->TranslationByteArray();
185 int length = data->DeoptCount();
186 for (int i = 0; i < length; i++) {
187 if (data->AstId(i) == ast_id) {
188 TranslationIterator it(translations, data->TranslationIndex(i)->value());
189 int value = it.Next();
190 ASSERT(Translation::BEGIN == static_cast<Translation::Opcode>(value));
191 // Read the number of frames.
192 value = it.Next();
193 if (value == 1) return i;
194 }
195 }
196 UNREACHABLE();
197 return -1;
198 }
199
200
201 void Deoptimizer::DoComputeOsrOutputFrame() {
202 DeoptimizationInputData* data = DeoptimizationInputData::cast(
203 compiled_code_->deoptimization_data());
204 unsigned ast_id = data->OsrAstId()->value();
205
206 int bailout_id = LookupBailoutId(data, BailoutId(ast_id));
207 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
208 ByteArray* translations = data->TranslationByteArray();
209
210 TranslationIterator iterator(translations, translation_index);
211 Translation::Opcode opcode =
212 static_cast<Translation::Opcode>(iterator.Next());
213 ASSERT(Translation::BEGIN == opcode);
214 USE(opcode);
215 int count = iterator.Next();
216 iterator.Skip(1); // Drop JS frame count.
217 ASSERT(count == 1);
218 USE(count);
219
220 opcode = static_cast<Translation::Opcode>(iterator.Next());
221 USE(opcode);
222 ASSERT(Translation::JS_FRAME == opcode);
223 unsigned node_id = iterator.Next();
224 USE(node_id);
225 ASSERT(node_id == ast_id);
226 int closure_id = iterator.Next();
227 USE(closure_id);
228 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
229 unsigned height = iterator.Next();
230 unsigned height_in_bytes = height * kPointerSize;
231 USE(height_in_bytes);
232
233 unsigned fixed_size = ComputeFixedSize(function_);
234 unsigned input_frame_size = input_->GetFrameSize();
235 ASSERT(fixed_size + height_in_bytes == input_frame_size);
236
237 unsigned stack_slot_size = compiled_code_->stack_slots() * kPointerSize;
238 unsigned outgoing_height = data->ArgumentsStackHeight(bailout_id)->value();
239 unsigned outgoing_size = outgoing_height * kPointerSize;
240 unsigned output_frame_size = fixed_size + stack_slot_size + outgoing_size;
241 ASSERT(outgoing_size == 0); // OSR does not happen in the middle of a call.
242
243 if (FLAG_trace_osr) {
244 PrintF("[on-stack replacement: begin 0x%08" V8PRIxPTR " ",
245 reinterpret_cast<intptr_t>(function_));
246 PrintFunctionName();
247 PrintF(" => node=%u, frame=%d->%d]\n",
248 ast_id,
249 input_frame_size,
250 output_frame_size);
251 }
252
253 // There's only one output frame in the OSR case.
254 output_count_ = 1;
255 output_ = new FrameDescription*[1];
256 output_[0] = new(output_frame_size) FrameDescription(
257 output_frame_size, function_);
258 output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
259
260 // Clear the incoming parameters in the optimized frame to avoid
261 // confusing the garbage collector.
262 unsigned output_offset = output_frame_size - kPointerSize;
263 int parameter_count = function_->shared()->formal_parameter_count() + 1;
264 for (int i = 0; i < parameter_count; ++i) {
265 output_[0]->SetFrameSlot(output_offset, 0);
266 output_offset -= kPointerSize;
267 }
268
269 // Translate the incoming parameters. This may overwrite some of the
270 // incoming argument slots we've just cleared.
271 int input_offset = input_frame_size - kPointerSize;
272 bool ok = true;
273 int limit = input_offset - (parameter_count * kPointerSize);
274 while (ok && input_offset > limit) {
275 ok = DoOsrTranslateCommand(&iterator, &input_offset);
276 }
277
278 // There are no translation commands for the caller's pc and fp, the
279 // context, and the function. Set them up explicitly.
280 for (int i = StandardFrameConstants::kCallerPCOffset;
281 ok && i >= StandardFrameConstants::kMarkerOffset;
282 i -= kPointerSize) {
283 uint32_t input_value = input_->GetFrameSlot(input_offset);
284 if (FLAG_trace_osr) {
285 const char* name = "UNKNOWN";
286 switch (i) {
287 case StandardFrameConstants::kCallerPCOffset:
288 name = "caller's pc";
289 break;
290 case StandardFrameConstants::kCallerFPOffset:
291 name = "fp";
292 break;
293 case StandardFrameConstants::kContextOffset:
294 name = "context";
295 break;
296 case StandardFrameConstants::kMarkerOffset:
297 name = "function";
298 break;
299 }
300 PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
301 output_offset,
302 input_value,
303 input_offset,
304 name);
305 }
306
307 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
308 input_offset -= kPointerSize;
309 output_offset -= kPointerSize;
310 }
311
312 // Translate the rest of the frame.
313 while (ok && input_offset >= 0) {
314 ok = DoOsrTranslateCommand(&iterator, &input_offset);
315 }
316
317 // If translation of any command failed, continue using the input frame.
318 if (!ok) {
319 delete output_[0];
320 output_[0] = input_;
321 output_[0]->SetPc(reinterpret_cast<uint32_t>(from_));
322 } else {
323 // Set up the frame pointer and the context pointer.
324 output_[0]->SetRegister(fp.code(), input_->GetRegister(fp.code()));
325 output_[0]->SetRegister(cp.code(), input_->GetRegister(cp.code()));
326
327 unsigned pc_offset = data->OsrPcOffset()->value();
328 uint32_t pc = reinterpret_cast<uint32_t>(
329 compiled_code_->entry() + pc_offset);
330 output_[0]->SetPc(pc);
331 }
332 Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
333 output_[0]->SetContinuation(
334 reinterpret_cast<uint32_t>(continuation->entry()));
335
336 if (FLAG_trace_osr) {
337 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
338 ok ? "finished" : "aborted",
339 reinterpret_cast<intptr_t>(function_));
340 PrintFunctionName();
341 PrintF(" => pc=0x%0x]\n", output_[0]->GetPc());
342 }
343 }
344
345
346 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { 183 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
347 // Set the register values. The values are not important as there are no 184 // Set the register values. The values are not important as there are no
348 // callee saved registers in JavaScript frames, so all registers are 185 // callee saved registers in JavaScript frames, so all registers are
349 // spilled. Registers fp and sp are set to the correct values though. 186 // spilled. Registers fp and sp are set to the correct values though.
350 187
351 for (int i = 0; i < Register::kNumRegisters; i++) { 188 for (int i = 0; i < Register::kNumRegisters; i++) {
352 input_->SetRegister(i, i * 4); 189 input_->SetRegister(i, i * 4);
353 } 190 }
354 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp())); 191 input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
355 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp())); 192 input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) { 385 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) {
549 if (i == kDoubleRegZero.code()) continue; 386 if (i == kDoubleRegZero.code()) continue;
550 if (i == kScratchDoubleReg.code()) continue; 387 if (i == kScratchDoubleReg.code()) continue;
551 388
552 const DwVfpRegister reg = DwVfpRegister::from_code(i); 389 const DwVfpRegister reg = DwVfpRegister::from_code(i);
553 __ vldr(reg, r1, src_offset, i < 16 ? al : ne); 390 __ vldr(reg, r1, src_offset, i < 16 ? al : ne);
554 src_offset += kDoubleSize; 391 src_offset += kDoubleSize;
555 } 392 }
556 393
557 // Push state, pc, and continuation from the last output frame. 394 // Push state, pc, and continuation from the last output frame.
558 if (type() != OSR) { 395 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset()));
559 __ ldr(r6, MemOperand(r2, FrameDescription::state_offset())); 396 __ push(r6);
560 __ push(r6);
561 }
562
563 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset())); 397 __ ldr(r6, MemOperand(r2, FrameDescription::pc_offset()));
564 __ push(r6); 398 __ push(r6);
565 __ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset())); 399 __ ldr(r6, MemOperand(r2, FrameDescription::continuation_offset()));
566 __ push(r6); 400 __ push(r6);
567 401
568 // Push the registers from the last output frame. 402 // Push the registers from the last output frame.
569 for (int i = kNumberOfRegisters - 1; i >= 0; i--) { 403 for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
570 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 404 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
571 __ ldr(r6, MemOperand(r2, offset)); 405 __ ldr(r6, MemOperand(r2, offset));
572 __ push(r6); 406 __ push(r6);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 443
610 444
611 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { 445 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
612 SetFrameSlot(offset, value); 446 SetFrameSlot(offset, value);
613 } 447 }
614 448
615 449
616 #undef __ 450 #undef __
617 451
618 } } // namespace v8::internal 452 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698