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

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

Issue 9265004: Support inlining at call-sites with mismatched number of arguments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: finished implementation, extended tests, ported to x64&arm Created 8 years, 11 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 2011 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
11 // with the distribution. 11 // with the distribution.
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 int bailout_id = LookupBailoutId(data, ast_id); 199 int bailout_id = LookupBailoutId(data, ast_id);
200 unsigned translation_index = data->TranslationIndex(bailout_id)->value(); 200 unsigned translation_index = data->TranslationIndex(bailout_id)->value();
201 ByteArray* translations = data->TranslationByteArray(); 201 ByteArray* translations = data->TranslationByteArray();
202 202
203 TranslationIterator iterator(translations, translation_index); 203 TranslationIterator iterator(translations, translation_index);
204 Translation::Opcode opcode = 204 Translation::Opcode opcode =
205 static_cast<Translation::Opcode>(iterator.Next()); 205 static_cast<Translation::Opcode>(iterator.Next());
206 ASSERT(Translation::BEGIN == opcode); 206 ASSERT(Translation::BEGIN == opcode);
207 USE(opcode); 207 USE(opcode);
208 int count = iterator.Next(); 208 int count = iterator.Next();
209 iterator.Skip(1); // Drop JS frame count.
209 ASSERT(count == 1); 210 ASSERT(count == 1);
210 USE(count); 211 USE(count);
211 212
212 opcode = static_cast<Translation::Opcode>(iterator.Next()); 213 opcode = static_cast<Translation::Opcode>(iterator.Next());
213 USE(opcode); 214 USE(opcode);
214 ASSERT(Translation::FRAME == opcode); 215 ASSERT(Translation::JS_FRAME == opcode);
215 unsigned node_id = iterator.Next(); 216 unsigned node_id = iterator.Next();
216 USE(node_id); 217 USE(node_id);
217 ASSERT(node_id == ast_id); 218 ASSERT(node_id == ast_id);
218 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next())); 219 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator.Next()));
219 USE(function); 220 USE(function);
220 ASSERT(function == function_); 221 ASSERT(function == function_);
221 unsigned height = iterator.Next(); 222 unsigned height = iterator.Next();
222 unsigned height_in_bytes = height * kPointerSize; 223 unsigned height_in_bytes = height * kPointerSize;
223 USE(height_in_bytes); 224 USE(height_in_bytes);
224 225
(...skipping 18 matching lines...) Expand all
243 } 244 }
244 245
245 // There's only one output frame in the OSR case. 246 // There's only one output frame in the OSR case.
246 output_count_ = 1; 247 output_count_ = 1;
247 output_ = new FrameDescription*[1]; 248 output_ = new FrameDescription*[1];
248 output_[0] = new(output_frame_size) FrameDescription( 249 output_[0] = new(output_frame_size) FrameDescription(
249 output_frame_size, function_); 250 output_frame_size, function_);
250 #ifdef DEBUG 251 #ifdef DEBUG
251 output_[0]->SetKind(Code::OPTIMIZED_FUNCTION); 252 output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
252 #endif 253 #endif
254 output_[0]->SetType(StackFrame::JAVA_SCRIPT);
253 255
254 // Clear the incoming parameters in the optimized frame to avoid 256 // Clear the incoming parameters in the optimized frame to avoid
255 // confusing the garbage collector. 257 // confusing the garbage collector.
256 unsigned output_offset = output_frame_size - kPointerSize; 258 unsigned output_offset = output_frame_size - kPointerSize;
257 int parameter_count = function_->shared()->formal_parameter_count() + 1; 259 int parameter_count = function_->shared()->formal_parameter_count() + 1;
258 for (int i = 0; i < parameter_count; ++i) { 260 for (int i = 0; i < parameter_count; ++i) {
259 output_[0]->SetFrameSlot(output_offset, 0); 261 output_[0]->SetFrameSlot(output_offset, 0);
260 output_offset -= kPointerSize; 262 output_offset -= kPointerSize;
261 } 263 }
262 264
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 if (FLAG_trace_osr) { 333 if (FLAG_trace_osr) {
332 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ", 334 PrintF("[on-stack replacement translation %s: 0x%08" V8PRIxPTR " ",
333 ok ? "finished" : "aborted", 335 ok ? "finished" : "aborted",
334 reinterpret_cast<intptr_t>(function)); 336 reinterpret_cast<intptr_t>(function));
335 function->PrintName(); 337 function->PrintName();
336 PrintF(" => pc=0x%0" V8PRIxPTR "]\n", output_[0]->GetPc()); 338 PrintF(" => pc=0x%0" V8PRIxPTR "]\n", output_[0]->GetPc());
337 } 339 }
338 } 340 }
339 341
340 342
341 void Deoptimizer::DoComputeFrame(TranslationIterator* iterator, 343 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
342 int frame_index) { 344 int frame_index) {
343 // Read the ast node id, function, and frame height for this output frame. 345 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
344 Translation::Opcode opcode = 346 unsigned height = iterator->Next();
345 static_cast<Translation::Opcode>(iterator->Next()); 347 unsigned height_in_bytes = height * kPointerSize;
346 USE(opcode); 348 if (FLAG_trace_deopt) {
347 ASSERT(Translation::FRAME == opcode); 349 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
350 }
351
352 unsigned fixed_frame_size = 5 * kPointerSize;
353 unsigned input_frame_size = input_->GetFrameSize();
354 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
355
356 // Allocate and store the output frame description.
357 FrameDescription* output_frame =
358 new(output_frame_size) FrameDescription(output_frame_size, function);
359 #ifdef DEBUG
360 output_frame->SetKind(Code::BUILTIN);
361 #endif
362 output_frame->SetType(StackFrame::ARGUMENTS_ADAPTOR);
363
364 // Arguments adaptor can not be topmost or bottommost.
365 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
366 ASSERT(output_[frame_index] == NULL);
367 output_[frame_index] = output_frame;
368
369 // The top address for the bottommost output frame can be computed from
370 // the input frame pointer and the output frame's height. For all
371 // subsequent output frames, it can be computed from the previous one's
372 // top address and the current frame's size.
373 intptr_t top_address;
374 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
375 output_frame->SetTop(top_address);
376
377 // Compute the incoming parameter translation.
378 int parameter_count = height;
379 unsigned output_offset = output_frame_size;
380 unsigned input_offset = input_frame_size;
381 for (int i = 0; i < parameter_count; ++i) {
382 output_offset -= kPointerSize;
383 DoTranslateCommand(iterator, frame_index, output_offset);
384 }
385 input_offset -= (parameter_count * kPointerSize);
386
387 // Compute caller's PC
388 output_offset -= kPointerSize;
389 input_offset -= kPointerSize;
390 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
391 output_frame->SetFrameSlot(output_offset, callers_pc);
392 if (FLAG_trace_deopt) {
393 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
394 V8PRIxPTR " ; caller's pc\n",
395 top_address + output_offset, output_offset, callers_pc);
396 }
397
398 // Compute caller's FP
399 output_offset -= kPointerSize;
400 input_offset -= kPointerSize;
401 intptr_t value = output_[frame_index - 1]->GetFp();
402 output_frame->SetFrameSlot(output_offset, value);
403 intptr_t fp_value = top_address + output_offset;
404 output_frame->SetFp(fp_value);
405 if (FLAG_trace_deopt) {
406 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
407 V8PRIxPTR " ; caller's fp\n",
408 fp_value, output_offset, value);
409 }
410
411 // For the bottommost output frame the context can be gotten from the input
412 // frame. For all subsequent output frames it can be gotten from the function
413 // so long as we don't inline functions that need local contexts.
414 output_offset -= kPointerSize;
415 input_offset -= kPointerSize;
416 intptr_t context = reinterpret_cast<intptr_t>(
417 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
418 output_frame->SetFrameSlot(output_offset, context);
419 if (FLAG_trace_deopt) {
420 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
421 V8PRIxPTR " ; context (adaptor sentinel)\n",
422 top_address + output_offset, output_offset, context);
423 }
424
425 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
426 output_offset -= kPointerSize;
427 input_offset -= kPointerSize;
428 value = reinterpret_cast<intptr_t>(function);
429 output_frame->SetFrameSlot(output_offset, value);
430 if (FLAG_trace_deopt) {
431 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
432 V8PRIxPTR " ; function\n",
433 top_address + output_offset, output_offset, value);
434 }
435
436 // Number of incomming arguments.
437 output_offset -= kPointerSize;
438 input_offset -= kPointerSize;
439 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
440 output_frame->SetFrameSlot(output_offset, value);
441 if (FLAG_trace_deopt) {
442 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
443 V8PRIxPTR " ; argc (%d)\n",
444 top_address + output_offset, output_offset, value, height - 1);
445 }
446
447 ASSERT(0 == output_offset);
448
449 Builtins* builtins = isolate_->builtins();
450 Code* adaptor_trampoline =
451 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
452 intptr_t pc_value = reinterpret_cast<intptr_t>(
453 adaptor_trampoline->instruction_start() +
454 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
455 output_frame->SetPc(pc_value);
456 }
457
458
459 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
460 int frame_index) {
348 int node_id = iterator->Next(); 461 int node_id = iterator->Next();
349 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 462 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
350 unsigned height = iterator->Next(); 463 unsigned height = iterator->Next();
351 unsigned height_in_bytes = height * kPointerSize; 464 unsigned height_in_bytes = height * kPointerSize;
352 if (FLAG_trace_deopt) { 465 if (FLAG_trace_deopt) {
353 PrintF(" translating "); 466 PrintF(" translating ");
354 function->PrintName(); 467 function->PrintName();
355 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes); 468 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
356 } 469 }
357 470
358 // The 'fixed' part of the frame consists of the incoming parameters and 471 // The 'fixed' part of the frame consists of the incoming parameters and
359 // the part described by JavaScriptFrameConstants. 472 // the part described by JavaScriptFrameConstants.
360 unsigned fixed_frame_size = ComputeFixedSize(function); 473 unsigned fixed_frame_size = ComputeFixedSize(function);
361 unsigned input_frame_size = input_->GetFrameSize(); 474 unsigned input_frame_size = input_->GetFrameSize();
362 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 475 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
363 476
364 // Allocate and store the output frame description. 477 // Allocate and store the output frame description.
365 FrameDescription* output_frame = 478 FrameDescription* output_frame =
366 new(output_frame_size) FrameDescription(output_frame_size, function); 479 new(output_frame_size) FrameDescription(output_frame_size, function);
367 #ifdef DEBUG 480 #ifdef DEBUG
368 output_frame->SetKind(Code::FUNCTION); 481 output_frame->SetKind(Code::FUNCTION);
369 #endif 482 #endif
483 output_frame->SetType(StackFrame::JAVA_SCRIPT);
370 484
371 bool is_bottommost = (0 == frame_index); 485 bool is_bottommost = (0 == frame_index);
372 bool is_topmost = (output_count_ - 1 == frame_index); 486 bool is_topmost = (output_count_ - 1 == frame_index);
373 ASSERT(frame_index >= 0 && frame_index < output_count_); 487 ASSERT(frame_index >= 0 && frame_index < output_count_);
374 ASSERT(output_[frame_index] == NULL); 488 ASSERT(output_[frame_index] == NULL);
375 output_[frame_index] = output_frame; 489 output_[frame_index] = output_frame;
376 490
377 // The top address for the bottommost output frame can be computed from 491 // The top address for the bottommost output frame can be computed from
378 // the input frame pointer and the output frame's height. For all 492 // the input frame pointer and the output frame's height. For all
379 // subsequent output frames, it can be computed from the previous one's 493 // subsequent output frames, it can be computed from the previous one's
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 } 857 }
744 __ bind(&done); 858 __ bind(&done);
745 } 859 }
746 860
747 #undef __ 861 #undef __
748 862
749 863
750 } } // namespace v8::internal 864 } } // namespace v8::internal
751 865
752 #endif // V8_TARGET_ARCH_X64 866 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/ia32/frames-ia32.h ('K') | « src/x64/builtins-x64.cc ('k') | src/x64/frames-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698