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

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

Issue 9304001: Implement inlining of constructor calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed moar comments by Vyacheslav Egorov. Created 8 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/x64/builtins-x64.cc ('k') | src/x64/full-codegen-x64.cc » ('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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 340 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
341 int frame_index) { 341 int frame_index) {
342 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 342 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
343 unsigned height = iterator->Next(); 343 unsigned height = iterator->Next();
344 unsigned height_in_bytes = height * kPointerSize; 344 unsigned height_in_bytes = height * kPointerSize;
345 if (FLAG_trace_deopt) { 345 if (FLAG_trace_deopt) {
346 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes); 346 PrintF(" translating arguments adaptor => height=%d\n", height_in_bytes);
347 } 347 }
348 348
349 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize; 349 unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
350 unsigned input_frame_size = input_->GetFrameSize();
351 unsigned output_frame_size = height_in_bytes + fixed_frame_size; 350 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
352 351
353 // Allocate and store the output frame description. 352 // Allocate and store the output frame description.
354 FrameDescription* output_frame = 353 FrameDescription* output_frame =
355 new(output_frame_size) FrameDescription(output_frame_size, function); 354 new(output_frame_size) FrameDescription(output_frame_size, function);
356 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR); 355 output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
357 356
358 // Arguments adaptor can not be topmost or bottommost. 357 // Arguments adaptor can not be topmost or bottommost.
359 ASSERT(frame_index > 0 && frame_index < output_count_ - 1); 358 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
360 ASSERT(output_[frame_index] == NULL); 359 ASSERT(output_[frame_index] == NULL);
361 output_[frame_index] = output_frame; 360 output_[frame_index] = output_frame;
362 361
363 // The top address of the frame is computed from the previous 362 // The top address of the frame is computed from the previous
364 // frame's top and this frame's size. 363 // frame's top and this frame's size.
365 intptr_t top_address; 364 intptr_t top_address;
366 top_address = output_[frame_index - 1]->GetTop() - output_frame_size; 365 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
367 output_frame->SetTop(top_address); 366 output_frame->SetTop(top_address);
368 367
369 // Compute the incoming parameter translation. 368 // Compute the incoming parameter translation.
370 int parameter_count = height; 369 int parameter_count = height;
371 unsigned output_offset = output_frame_size; 370 unsigned output_offset = output_frame_size;
372 unsigned input_offset = input_frame_size;
373 for (int i = 0; i < parameter_count; ++i) { 371 for (int i = 0; i < parameter_count; ++i) {
374 output_offset -= kPointerSize; 372 output_offset -= kPointerSize;
375 DoTranslateCommand(iterator, frame_index, output_offset); 373 DoTranslateCommand(iterator, frame_index, output_offset);
376 } 374 }
377 input_offset -= (parameter_count * kPointerSize);
378 375
379 // Read caller's PC from the previous frame. 376 // Read caller's PC from the previous frame.
380 output_offset -= kPointerSize; 377 output_offset -= kPointerSize;
381 input_offset -= kPointerSize;
382 intptr_t callers_pc = output_[frame_index - 1]->GetPc(); 378 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
383 output_frame->SetFrameSlot(output_offset, callers_pc); 379 output_frame->SetFrameSlot(output_offset, callers_pc);
384 if (FLAG_trace_deopt) { 380 if (FLAG_trace_deopt) {
385 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 381 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
386 V8PRIxPTR " ; caller's pc\n", 382 V8PRIxPTR " ; caller's pc\n",
387 top_address + output_offset, output_offset, callers_pc); 383 top_address + output_offset, output_offset, callers_pc);
388 } 384 }
389 385
390 // Read caller's FP from the previous frame, and set this frame's FP. 386 // Read caller's FP from the previous frame, and set this frame's FP.
391 output_offset -= kPointerSize; 387 output_offset -= kPointerSize;
392 input_offset -= kPointerSize;
393 intptr_t value = output_[frame_index - 1]->GetFp(); 388 intptr_t value = output_[frame_index - 1]->GetFp();
394 output_frame->SetFrameSlot(output_offset, value); 389 output_frame->SetFrameSlot(output_offset, value);
395 intptr_t fp_value = top_address + output_offset; 390 intptr_t fp_value = top_address + output_offset;
396 output_frame->SetFp(fp_value); 391 output_frame->SetFp(fp_value);
397 if (FLAG_trace_deopt) { 392 if (FLAG_trace_deopt) {
398 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 393 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
399 V8PRIxPTR " ; caller's fp\n", 394 V8PRIxPTR " ; caller's fp\n",
400 fp_value, output_offset, value); 395 fp_value, output_offset, value);
401 } 396 }
402 397
403 // A marker value is used in place of the context. 398 // A marker value is used in place of the context.
404 output_offset -= kPointerSize; 399 output_offset -= kPointerSize;
405 input_offset -= kPointerSize;
406 intptr_t context = reinterpret_cast<intptr_t>( 400 intptr_t context = reinterpret_cast<intptr_t>(
407 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 401 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
408 output_frame->SetFrameSlot(output_offset, context); 402 output_frame->SetFrameSlot(output_offset, context);
409 if (FLAG_trace_deopt) { 403 if (FLAG_trace_deopt) {
410 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 404 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
411 V8PRIxPTR " ; context (adaptor sentinel)\n", 405 V8PRIxPTR " ; context (adaptor sentinel)\n",
412 top_address + output_offset, output_offset, context); 406 top_address + output_offset, output_offset, context);
413 } 407 }
414 408
415 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME. 409 // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
416 output_offset -= kPointerSize; 410 output_offset -= kPointerSize;
417 input_offset -= kPointerSize;
418 value = reinterpret_cast<intptr_t>(function); 411 value = reinterpret_cast<intptr_t>(function);
419 output_frame->SetFrameSlot(output_offset, value); 412 output_frame->SetFrameSlot(output_offset, value);
420 if (FLAG_trace_deopt) { 413 if (FLAG_trace_deopt) {
421 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 414 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
422 V8PRIxPTR " ; function\n", 415 V8PRIxPTR " ; function\n",
423 top_address + output_offset, output_offset, value); 416 top_address + output_offset, output_offset, value);
424 } 417 }
425 418
426 // Number of incoming arguments. 419 // Number of incoming arguments.
427 output_offset -= kPointerSize; 420 output_offset -= kPointerSize;
428 input_offset -= kPointerSize;
429 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1)); 421 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
430 output_frame->SetFrameSlot(output_offset, value); 422 output_frame->SetFrameSlot(output_offset, value);
431 if (FLAG_trace_deopt) { 423 if (FLAG_trace_deopt) {
432 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 424 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
433 V8PRIxPTR " ; argc (%d)\n", 425 V8PRIxPTR " ; argc (%d)\n",
434 top_address + output_offset, output_offset, value, height - 1); 426 top_address + output_offset, output_offset, value, height - 1);
435 } 427 }
436 428
437 ASSERT(0 == output_offset); 429 ASSERT(0 == output_offset);
438 430
439 Builtins* builtins = isolate_->builtins(); 431 Builtins* builtins = isolate_->builtins();
440 Code* adaptor_trampoline = 432 Code* adaptor_trampoline =
441 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline); 433 builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
442 intptr_t pc_value = reinterpret_cast<intptr_t>( 434 intptr_t pc_value = reinterpret_cast<intptr_t>(
443 adaptor_trampoline->instruction_start() + 435 adaptor_trampoline->instruction_start() +
444 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value()); 436 isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
445 output_frame->SetPc(pc_value); 437 output_frame->SetPc(pc_value);
446 } 438 }
447 439
448 440
441 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
442 int frame_index) {
443 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
444 unsigned height = iterator->Next();
445 unsigned height_in_bytes = height * kPointerSize;
446 if (FLAG_trace_deopt) {
447 PrintF(" translating construct stub => height=%d\n", height_in_bytes);
448 }
449
450 unsigned fixed_frame_size = 6 * kPointerSize;
451 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
452
453 // Allocate and store the output frame description.
454 FrameDescription* output_frame =
455 new(output_frame_size) FrameDescription(output_frame_size, function);
456 output_frame->SetFrameType(StackFrame::CONSTRUCT);
457
458 // Construct stub can not be topmost or bottommost.
459 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
460 ASSERT(output_[frame_index] == NULL);
461 output_[frame_index] = output_frame;
462
463 // The top address of the frame is computed from the previous
464 // frame's top and this frame's size.
465 intptr_t top_address;
466 top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
467 output_frame->SetTop(top_address);
468
469 // Compute the incoming parameter translation.
470 int parameter_count = height;
471 unsigned output_offset = output_frame_size;
472 for (int i = 0; i < parameter_count; ++i) {
473 output_offset -= kPointerSize;
474 DoTranslateCommand(iterator, frame_index, output_offset);
475 }
476
477 // Read caller's PC from the previous frame.
478 output_offset -= kPointerSize;
479 intptr_t callers_pc = output_[frame_index - 1]->GetPc();
480 output_frame->SetFrameSlot(output_offset, callers_pc);
481 if (FLAG_trace_deopt) {
482 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
483 V8PRIxPTR " ; caller's pc\n",
484 top_address + output_offset, output_offset, callers_pc);
485 }
486
487 // Read caller's FP from the previous frame, and set this frame's FP.
488 output_offset -= kPointerSize;
489 intptr_t value = output_[frame_index - 1]->GetFp();
490 output_frame->SetFrameSlot(output_offset, value);
491 intptr_t fp_value = top_address + output_offset;
492 output_frame->SetFp(fp_value);
493 if (FLAG_trace_deopt) {
494 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
495 V8PRIxPTR " ; caller's fp\n",
496 fp_value, output_offset, value);
497 }
498
499 // The context can be gotten from the previous frame.
500 output_offset -= kPointerSize;
501 value = output_[frame_index - 1]->GetContext();
502 output_frame->SetFrameSlot(output_offset, value);
503 if (FLAG_trace_deopt) {
504 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
505 V8PRIxPTR " ; context\n",
506 top_address + output_offset, output_offset, value);
507 }
508
509 // A marker value is used in place of the function.
510 output_offset -= kPointerSize;
511 value = reinterpret_cast<intptr_t>(Smi::FromInt(StackFrame::CONSTRUCT));
512 output_frame->SetFrameSlot(output_offset, value);
513 if (FLAG_trace_deopt) {
514 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
515 V8PRIxPTR " ; function (construct sentinel)\n",
516 top_address + output_offset, output_offset, value);
517 }
518
519 // Number of incoming arguments.
520 output_offset -= kPointerSize;
521 value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
522 output_frame->SetFrameSlot(output_offset, value);
523 if (FLAG_trace_deopt) {
524 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
525 V8PRIxPTR " ; argc (%d)\n",
526 top_address + output_offset, output_offset, value, height - 1);
527 }
528
529 // The newly allocated object was passed as receiver in the artificial
530 // constructor stub environment created by HEnvironment::CopyForInlining().
531 output_offset -= kPointerSize;
532 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
533 output_frame->SetFrameSlot(output_offset, value);
534 if (FLAG_trace_deopt) {
535 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
536 V8PRIxPTR " ; allocated receiver\n",
537 top_address + output_offset, output_offset, value);
538 }
539
540 ASSERT(0 == output_offset);
541
542 Builtins* builtins = isolate_->builtins();
543 Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
544 intptr_t pc = reinterpret_cast<intptr_t>(
545 construct_stub->instruction_start() +
546 isolate_->heap()->construct_stub_deopt_pc_offset()->value());
547 output_frame->SetPc(pc);
548 }
549
550
449 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator, 551 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
450 int frame_index) { 552 int frame_index) {
451 int node_id = iterator->Next(); 553 int node_id = iterator->Next();
452 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next())); 554 JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
453 unsigned height = iterator->Next(); 555 unsigned height = iterator->Next();
454 unsigned height_in_bytes = height * kPointerSize; 556 unsigned height_in_bytes = height * kPointerSize;
455 if (FLAG_trace_deopt) { 557 if (FLAG_trace_deopt) {
456 PrintF(" translating "); 558 PrintF(" translating ");
457 function->PrintName(); 559 function->PrintName();
458 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes); 560 PrintF(" => node=%d, height=%d\n", node_id, height_in_bytes);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
548 // frame. For all subsequent output frames it can be gotten from the function 650 // frame. For all subsequent output frames it can be gotten from the function
549 // so long as we don't inline functions that need local contexts. 651 // so long as we don't inline functions that need local contexts.
550 output_offset -= kPointerSize; 652 output_offset -= kPointerSize;
551 input_offset -= kPointerSize; 653 input_offset -= kPointerSize;
552 if (is_bottommost) { 654 if (is_bottommost) {
553 value = input_->GetFrameSlot(input_offset); 655 value = input_->GetFrameSlot(input_offset);
554 } else { 656 } else {
555 value = reinterpret_cast<intptr_t>(function->context()); 657 value = reinterpret_cast<intptr_t>(function->context());
556 } 658 }
557 output_frame->SetFrameSlot(output_offset, value); 659 output_frame->SetFrameSlot(output_offset, value);
660 output_frame->SetContext(value);
558 if (is_topmost) output_frame->SetRegister(rsi.code(), value); 661 if (is_topmost) output_frame->SetRegister(rsi.code(), value);
559 if (FLAG_trace_deopt) { 662 if (FLAG_trace_deopt) {
560 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" 663 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
561 V8PRIxPTR "; context\n", 664 V8PRIxPTR "; context\n",
562 top_address + output_offset, output_offset, value); 665 top_address + output_offset, output_offset, value);
563 } 666 }
564 667
565 // The function was mentioned explicitly in the BEGIN_FRAME. 668 // The function was mentioned explicitly in the BEGIN_FRAME.
566 output_offset -= kPointerSize; 669 output_offset -= kPointerSize;
567 input_offset -= kPointerSize; 670 input_offset -= kPointerSize;
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 } 947 }
845 __ bind(&done); 948 __ bind(&done);
846 } 949 }
847 950
848 #undef __ 951 #undef __
849 952
850 953
851 } } // namespace v8::internal 954 } } // namespace v8::internal
852 955
853 #endif // V8_TARGET_ARCH_X64 956 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698