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

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

Issue 18014003: Add X32 port into V8 (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 7 years, 5 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 #endif 77 #endif
78 DeoptimizationInputData* deopt_data = 78 DeoptimizationInputData* deopt_data =
79 DeoptimizationInputData::cast(code->deoptimization_data()); 79 DeoptimizationInputData::cast(code->deoptimization_data());
80 for (int i = 0; i < deopt_data->DeoptCount(); i++) { 80 for (int i = 0; i < deopt_data->DeoptCount(); i++) {
81 if (deopt_data->Pc(i)->value() == -1) continue; 81 if (deopt_data->Pc(i)->value() == -1) continue;
82 // Position where Call will be patched in. 82 // Position where Call will be patched in.
83 Address call_address = instruction_start + deopt_data->Pc(i)->value(); 83 Address call_address = instruction_start + deopt_data->Pc(i)->value();
84 // There is room enough to write a long call instruction because we pad 84 // There is room enough to write a long call instruction because we pad
85 // LLazyBailout instructions with nops if necessary. 85 // LLazyBailout instructions with nops if necessary.
86 CodePatcher patcher(call_address, Assembler::kCallInstructionLength); 86 CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
87 #ifndef V8_TARGET_ARCH_X32
87 patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY), 88 patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
88 RelocInfo::NONE64); 89 RelocInfo::NONE64);
90 #else
91 patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY),
92 RelocInfo::NONE32);
93 #endif
89 ASSERT(prev_call_address == NULL || 94 ASSERT(prev_call_address == NULL ||
90 call_address >= prev_call_address + patch_size()); 95 call_address >= prev_call_address + patch_size());
91 ASSERT(call_address + patch_size() <= code->instruction_end()); 96 ASSERT(call_address + patch_size() <= code->instruction_end());
92 #ifdef DEBUG 97 #ifdef DEBUG
93 prev_call_address = call_address; 98 prev_call_address = call_address;
94 #endif 99 #endif
95 } 100 }
96 101
97 // Add the deoptimizing code to the list. 102 // Add the deoptimizing code to the list.
98 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code); 103 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
(...skipping 10 matching lines...) Expand all
109 114
110 if (FLAG_trace_deopt) { 115 if (FLAG_trace_deopt) {
111 PrintF("[forced deoptimization: "); 116 PrintF("[forced deoptimization: ");
112 function->PrintName(); 117 function->PrintName();
113 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function)); 118 PrintF(" / %" V8PRIxPTR "]\n", reinterpret_cast<intptr_t>(function));
114 } 119 }
115 } 120 }
116 121
117 122
118 static const byte kJnsInstruction = 0x79; 123 static const byte kJnsInstruction = 0x79;
124 #ifndef V8_TARGET_ARCH_X32
119 static const byte kJnsOffset = 0x1d; 125 static const byte kJnsOffset = 0x1d;
126 #else
127 static const byte kJnsOffset = 0x14;
128 #endif
120 static const byte kCallInstruction = 0xe8; 129 static const byte kCallInstruction = 0xe8;
121 static const byte kNopByteOne = 0x66; 130 static const byte kNopByteOne = 0x66;
122 static const byte kNopByteTwo = 0x90; 131 static const byte kNopByteTwo = 0x90;
123 132
124 // The back edge bookkeeping code matches the pattern: 133 // The back edge bookkeeping code matches the pattern:
125 // 134 //
126 // add <profiling_counter>, <-delta> 135 // add <profiling_counter>, <-delta>
127 // jns ok 136 // jns ok
128 // call <stack guard> 137 // call <stack guard>
129 // ok: 138 // ok:
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 int limit = input_offset - (parameter_count * kPointerSize); 306 int limit = input_offset - (parameter_count * kPointerSize);
298 while (ok && input_offset > limit) { 307 while (ok && input_offset > limit) {
299 ok = DoOsrTranslateCommand(&iterator, &input_offset); 308 ok = DoOsrTranslateCommand(&iterator, &input_offset);
300 } 309 }
301 310
302 // There are no translation commands for the caller's pc and fp, the 311 // There are no translation commands for the caller's pc and fp, the
303 // context, and the function. Set them up explicitly. 312 // context, and the function. Set them up explicitly.
304 for (int i = StandardFrameConstants::kCallerPCOffset; 313 for (int i = StandardFrameConstants::kCallerPCOffset;
305 ok && i >= StandardFrameConstants::kMarkerOffset; 314 ok && i >= StandardFrameConstants::kMarkerOffset;
306 i -= kPointerSize) { 315 i -= kPointerSize) {
316 #ifdef V8_TARGET_ARCH_X32
317 if (i == StandardFrameConstants::kCallerPCOffset ||
318 i == StandardFrameConstants::kCallerFPOffset) {
319 // Set the high-32 bit of PC and FP to 0.
320 output_[0]->SetFrameSlot(output_offset, 0);
321 input_offset -= kPointerSize;
322 output_offset -= kPointerSize;
323 }
324 #endif
307 intptr_t input_value = input_->GetFrameSlot(input_offset); 325 intptr_t input_value = input_->GetFrameSlot(input_offset);
308 if (FLAG_trace_osr) { 326 if (FLAG_trace_osr) {
309 const char* name = "UNKNOWN"; 327 const char* name = "UNKNOWN";
310 switch (i) { 328 switch (i) {
311 case StandardFrameConstants::kCallerPCOffset: 329 case StandardFrameConstants::kCallerPCOffset:
312 name = "caller's pc"; 330 name = "caller's pc";
313 break; 331 break;
314 case StandardFrameConstants::kCallerFPOffset: 332 case StandardFrameConstants::kCallerFPOffset:
315 name = "fp"; 333 name = "fp";
316 break; 334 break;
317 case StandardFrameConstants::kContextOffset: 335 case StandardFrameConstants::kContextOffset:
318 name = "context"; 336 name = "context";
319 break; 337 break;
320 case StandardFrameConstants::kMarkerOffset: 338 case StandardFrameConstants::kMarkerOffset:
321 name = "function"; 339 name = "function";
322 break; 340 break;
323 } 341 }
324 PrintF(" [rsp + %d] <- 0x%08" V8PRIxPTR " ; [rsp + %d] " 342 PrintF(" [rsp + %d] <- 0x%08" V8PRIxPTR " ; [rsp + %d] "
325 "(fixed part - %s)\n", 343 "(fixed part - %s)\n",
326 output_offset, 344 output_offset,
327 input_value, 345 input_value,
328 input_offset, 346 input_offset,
329 name); 347 name);
330 } 348 }
331 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset)); 349 output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
332 input_offset -= kPointerSize; 350 input_offset -= kPointerSize;
333 output_offset -= kPointerSize; 351 output_offset -= kPointerSize;
352 #ifdef V8_TARGET_ARCH_X32
353 if (i == StandardFrameConstants::kCallerPCOffset) {
354 i -= kHWRegSize - kPointerSize;
355 }
356 #endif
334 } 357 }
335 358
336 // Translate the rest of the frame. 359 // Translate the rest of the frame.
337 while (ok && input_offset >= 0) { 360 while (ok && input_offset >= 0) {
338 ok = DoOsrTranslateCommand(&iterator, &input_offset); 361 ok = DoOsrTranslateCommand(&iterator, &input_offset);
339 } 362 }
340 363
341 // If translation of any command failed, continue using the input frame. 364 // If translation of any command failed, continue using the input frame.
342 if (!ok) { 365 if (!ok) {
343 delete output_[0]; 366 delete output_[0];
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 input_->SetRegister(i, i * 4); 399 input_->SetRegister(i, i * 4);
377 } 400 }
378 input_->SetRegister(rsp.code(), reinterpret_cast<intptr_t>(frame->sp())); 401 input_->SetRegister(rsp.code(), reinterpret_cast<intptr_t>(frame->sp()));
379 input_->SetRegister(rbp.code(), reinterpret_cast<intptr_t>(frame->fp())); 402 input_->SetRegister(rbp.code(), reinterpret_cast<intptr_t>(frame->fp()));
380 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) { 403 for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
381 input_->SetDoubleRegister(i, 0.0); 404 input_->SetDoubleRegister(i, 0.0);
382 } 405 }
383 406
384 // Fill the frame content from the actual data on the frame. 407 // Fill the frame content from the actual data on the frame.
385 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { 408 for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
409 #ifndef V8_TARGET_ARCH_X32
386 input_->SetFrameSlot(i, Memory::uint64_at(tos + i)); 410 input_->SetFrameSlot(i, Memory::uint64_at(tos + i));
411 #else
412 input_->SetFrameSlot(i, Memory::uint32_at(tos + i));
413 #endif
387 } 414 }
388 } 415 }
389 416
390 417
391 void Deoptimizer::SetPlatformCompiledStubRegisters( 418 void Deoptimizer::SetPlatformCompiledStubRegisters(
392 FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { 419 FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) {
393 intptr_t handler = 420 intptr_t handler =
394 reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_); 421 reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_);
395 int params = descriptor->register_param_count_; 422 int params = descriptor->register_param_count_;
396 if (descriptor->stack_parameter_count_ != NULL) { 423 if (descriptor->stack_parameter_count_ != NULL) {
(...skipping 12 matching lines...) Expand all
409 } 436 }
410 437
411 438
412 bool Deoptimizer::HasAlignmentPadding(JSFunction* function) { 439 bool Deoptimizer::HasAlignmentPadding(JSFunction* function) {
413 // There is no dynamic alignment padding on x64 in the input frame. 440 // There is no dynamic alignment padding on x64 in the input frame.
414 return false; 441 return false;
415 } 442 }
416 443
417 444
418 #define __ masm()-> 445 #define __ masm()->
446 #define __k __
447 #define __q __
419 448
420 void Deoptimizer::EntryGenerator::Generate() { 449 void Deoptimizer::EntryGenerator::Generate() {
421 GeneratePrologue(); 450 GeneratePrologue();
422 451
423 // Save all general purpose registers before messing with them. 452 // Save all general purpose registers before messing with them.
424 const int kNumberOfRegisters = Register::kNumRegisters; 453 const int kNumberOfRegisters = Register::kNumRegisters;
425 454
426 const int kDoubleRegsSize = kDoubleSize * 455 const int kDoubleRegsSize = kDoubleSize *
427 XMMRegister::NumAllocatableRegisters(); 456 XMMRegister::NumAllocatableRegisters();
428 __ subq(rsp, Immediate(kDoubleRegsSize)); 457 __ subq(rsp, Immediate(kDoubleRegsSize));
429 458
430 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) { 459 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) {
431 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 460 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
432 int offset = i * kDoubleSize; 461 int offset = i * kDoubleSize;
433 __ movsd(Operand(rsp, offset), xmm_reg); 462 __ movsd(Operand(rsp, offset), xmm_reg);
434 } 463 }
435 464
436 // We push all registers onto the stack, even though we do not need 465 // We push all registers onto the stack, even though we do not need
437 // to restore all later. 466 // to restore all later.
438 for (int i = 0; i < kNumberOfRegisters; i++) { 467 for (int i = 0; i < kNumberOfRegisters; i++) {
439 Register r = Register::from_code(i); 468 Register r = Register::from_code(i);
440 __ push(r); 469 __k push(r);
441 } 470 }
442 471
472 #ifndef V8_TARGET_ARCH_X32
443 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize + 473 const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize +
444 kDoubleRegsSize; 474 kDoubleRegsSize;
475 #else
476 const int kSavedRegistersAreaSize = kNumberOfRegisters * kHWRegSize +
477 kDoubleRegsSize;
478 #endif
445 479
446 // We use this to keep the value of the fifth argument temporarily. 480 // We use this to keep the value of the fifth argument temporarily.
447 // Unfortunately we can't store it directly in r8 (used for passing 481 // Unfortunately we can't store it directly in r8 (used for passing
448 // this on linux), since it is another parameter passing register on windows. 482 // this on linux), since it is another parameter passing register on windows.
449 Register arg5 = r11; 483 Register arg5 = r11;
450 484
451 // Get the bailout id from the stack. 485 // Get the bailout id from the stack.
452 __ movq(arg_reg_3, Operand(rsp, kSavedRegistersAreaSize)); 486 __ movq(arg_reg_3, Operand(rsp, kSavedRegistersAreaSize));
453 487
454 // Get the address of the location in the code object if possible 488 // Get the address of the location in the code object if possible
455 // and compute the fp-to-sp delta in register arg5. 489 // and compute the fp-to-sp delta in register arg5.
456 if (type() == EAGER || type() == SOFT) { 490 if (type() == EAGER || type() == SOFT) {
457 __ Set(arg_reg_4, 0); 491 __ Set(arg_reg_4, 0);
458 __ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize)); 492 __q lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
459 } else { 493 } else {
494 #ifndef V8_TARGET_ARCH_X32
460 __ movq(arg_reg_4, 495 __ movq(arg_reg_4,
461 Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize)); 496 Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize));
462 __ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize)); 497 #else
498 __ movl(arg_reg_4, Operand(rsp, kSavedRegistersAreaSize + 1 * kHWRegSize));
499 #endif
500 __q lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize));
463 } 501 }
464 502
465 __ subq(arg5, rbp); 503 __ subq(arg5, rbp);
466 __ neg(arg5); 504 __ neg(arg5);
467 505
468 // Allocate a new deoptimizer object. 506 // Allocate a new deoptimizer object.
469 __ PrepareCallCFunction(6); 507 __ PrepareCallCFunction(6);
470 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 508 __ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
471 __ movq(arg_reg_1, rax); 509 __ movq(arg_reg_1, rax);
472 __ Set(arg_reg_2, type()); 510 __ Set(arg_reg_2, type());
(...skipping 13 matching lines...) Expand all
486 { AllowExternalCallThatCantCauseGC scope(masm()); 524 { AllowExternalCallThatCantCauseGC scope(masm());
487 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6); 525 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6);
488 } 526 }
489 // Preserve deoptimizer object in register rax and get the input 527 // Preserve deoptimizer object in register rax and get the input
490 // frame descriptor pointer. 528 // frame descriptor pointer.
491 __ movq(rbx, Operand(rax, Deoptimizer::input_offset())); 529 __ movq(rbx, Operand(rax, Deoptimizer::input_offset()));
492 530
493 // Fill in the input registers. 531 // Fill in the input registers.
494 for (int i = kNumberOfRegisters -1; i >= 0; i--) { 532 for (int i = kNumberOfRegisters -1; i >= 0; i--) {
495 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 533 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
534 #ifndef V8_TARGET_ARCH_X32
496 __ pop(Operand(rbx, offset)); 535 __ pop(Operand(rbx, offset));
536 #else
537 __ pop(kScratchRegister);
538 __ movl(Operand(rbx, offset), kScratchRegister);
539 #endif
497 } 540 }
498 541
499 // Fill in the double input registers. 542 // Fill in the double input registers.
500 int double_regs_offset = FrameDescription::double_registers_offset(); 543 int double_regs_offset = FrameDescription::double_registers_offset();
501 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { 544 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) {
502 int dst_offset = i * kDoubleSize + double_regs_offset; 545 int dst_offset = i * kDoubleSize + double_regs_offset;
503 __ pop(Operand(rbx, dst_offset)); 546 __k pop(Operand(rbx, dst_offset));
504 } 547 }
505 548
506 // Remove the bailout id from the stack. 549 // Remove the bailout id from the stack.
507 if (type() == EAGER || type() == SOFT) { 550 if (type() == EAGER || type() == SOFT) {
508 __ addq(rsp, Immediate(kPointerSize)); 551 __q addq(rsp, Immediate(kPointerSize));
509 } else { 552 } else {
510 __ addq(rsp, Immediate(2 * kPointerSize)); 553 __q addq(rsp, Immediate(2 * kPointerSize));
511 } 554 }
512 555
513 // Compute a pointer to the unwinding limit in register rcx; that is 556 // Compute a pointer to the unwinding limit in register rcx; that is
514 // the first stack slot not part of the input frame. 557 // the first stack slot not part of the input frame.
515 __ movq(rcx, Operand(rbx, FrameDescription::frame_size_offset())); 558 __ movq(rcx, Operand(rbx, FrameDescription::frame_size_offset()));
516 __ addq(rcx, rsp); 559 __ addq(rcx, rsp);
517 560
518 // Unwind the stack down to - but not including - the unwinding 561 // Unwind the stack down to - but not including - the unwinding
519 // limit and copy the contents of the activation frame to the input 562 // limit and copy the contents of the activation frame to the input
520 // frame description. 563 // frame description.
521 __ lea(rdx, Operand(rbx, FrameDescription::frame_content_offset())); 564 __ lea(rdx, Operand(rbx, FrameDescription::frame_content_offset()));
522 Label pop_loop_header; 565 Label pop_loop_header;
523 __ jmp(&pop_loop_header); 566 __ jmp(&pop_loop_header);
524 Label pop_loop; 567 Label pop_loop;
525 __ bind(&pop_loop); 568 __ bind(&pop_loop);
526 __ pop(Operand(rdx, 0)); 569 __ pop(Operand(rdx, 0));
527 __ addq(rdx, Immediate(sizeof(intptr_t))); 570 __ addq(rdx, Immediate(sizeof(intptr_t)));
528 __ bind(&pop_loop_header); 571 __ bind(&pop_loop_header);
529 __ cmpq(rcx, rsp); 572 __ cmpq(rcx, rsp);
530 __ j(not_equal, &pop_loop); 573 __ j(not_equal, &pop_loop);
531 574
532 // Compute the output frame in the deoptimizer. 575 // Compute the output frame in the deoptimizer.
533 __ push(rax); 576 __k push(rax);
534 __ PrepareCallCFunction(2); 577 __ PrepareCallCFunction(2);
535 __ movq(arg_reg_1, rax); 578 __ movq(arg_reg_1, rax);
536 __ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate())); 579 __ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate()));
537 { 580 {
538 AllowExternalCallThatCantCauseGC scope(masm()); 581 AllowExternalCallThatCantCauseGC scope(masm());
539 __ CallCFunction( 582 __ CallCFunction(
540 ExternalReference::compute_output_frames_function(isolate()), 2); 583 ExternalReference::compute_output_frames_function(isolate()), 2);
541 } 584 }
542 __ pop(rax); 585 __k pop(rax);
543 586
544 // Replace the current frame with the output frames. 587 // Replace the current frame with the output frames.
545 Label outer_push_loop, inner_push_loop, 588 Label outer_push_loop, inner_push_loop,
546 outer_loop_header, inner_loop_header; 589 outer_loop_header, inner_loop_header;
547 // Outer loop state: rax = current FrameDescription**, rdx = one past the 590 // Outer loop state: rax = current FrameDescription**, rdx = one past the
548 // last FrameDescription**. 591 // last FrameDescription**.
549 __ movl(rdx, Operand(rax, Deoptimizer::output_count_offset())); 592 __ movl(rdx, Operand(rax, Deoptimizer::output_count_offset()));
550 __ movq(rax, Operand(rax, Deoptimizer::output_offset())); 593 __ movq(rax, Operand(rax, Deoptimizer::output_offset()));
551 __ lea(rdx, Operand(rax, rdx, times_pointer_size, 0)); 594 __ lea(rdx, Operand(rax, rdx, times_pointer_size, 0));
552 __ jmp(&outer_loop_header); 595 __ jmp(&outer_loop_header);
(...skipping 14 matching lines...) Expand all
567 __ j(below, &outer_push_loop); 610 __ j(below, &outer_push_loop);
568 611
569 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) { 612 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) {
570 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i); 613 XMMRegister xmm_reg = XMMRegister::FromAllocationIndex(i);
571 int src_offset = i * kDoubleSize + double_regs_offset; 614 int src_offset = i * kDoubleSize + double_regs_offset;
572 __ movsd(xmm_reg, Operand(rbx, src_offset)); 615 __ movsd(xmm_reg, Operand(rbx, src_offset));
573 } 616 }
574 617
575 // Push state, pc, and continuation from the last output frame. 618 // Push state, pc, and continuation from the last output frame.
576 if (type() != OSR) { 619 if (type() != OSR) {
620 #ifdef V8_TARGET_ARCH_X32
621 __ Push(Immediate(0));
622 #endif
577 __ push(Operand(rbx, FrameDescription::state_offset())); 623 __ push(Operand(rbx, FrameDescription::state_offset()));
578 } 624 }
625 #ifdef V8_TARGET_ARCH_X32
626 __ Push(Immediate(0));
627 #endif
579 __ push(Operand(rbx, FrameDescription::pc_offset())); 628 __ push(Operand(rbx, FrameDescription::pc_offset()));
629 #ifdef V8_TARGET_ARCH_X32
630 __ Push(Immediate(0));
631 #endif
580 __ push(Operand(rbx, FrameDescription::continuation_offset())); 632 __ push(Operand(rbx, FrameDescription::continuation_offset()));
581 633
582 // Push the registers from the last output frame. 634 // Push the registers from the last output frame.
583 for (int i = 0; i < kNumberOfRegisters; i++) { 635 for (int i = 0; i < kNumberOfRegisters; i++) {
584 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 636 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
637 #ifndef V8_TARGET_ARCH_X32
585 __ push(Operand(rbx, offset)); 638 __ push(Operand(rbx, offset));
639 #else
640 __ movl(kScratchRegister, Operand(rbx, offset));
641 __ push(kScratchRegister);
642 #endif
586 } 643 }
587 644
588 // Restore the registers from the stack. 645 // Restore the registers from the stack.
589 for (int i = kNumberOfRegisters - 1; i >= 0 ; i--) { 646 for (int i = kNumberOfRegisters - 1; i >= 0 ; i--) {
590 Register r = Register::from_code(i); 647 Register r = Register::from_code(i);
591 // Do not restore rsp, simply pop the value into the next register 648 // Do not restore rsp, simply pop the value into the next register
592 // and overwrite this afterwards. 649 // and overwrite this afterwards.
593 if (r.is(rsp)) { 650 if (r.is(rsp)) {
594 ASSERT(i > 0); 651 ASSERT(i > 0);
595 r = Register::from_code(i - 1); 652 r = Register::from_code(i - 1);
596 } 653 }
597 __ pop(r); 654 __k pop(r);
598 } 655 }
599 656
600 // Set up the roots register. 657 // Set up the roots register.
601 __ InitializeRootRegister(); 658 __ InitializeRootRegister();
602 __ InitializeSmiConstantRegister(); 659 __ InitializeSmiConstantRegister();
603 660
604 // Return to the continuation point. 661 // Return to the continuation point.
605 __ ret(0); 662 __ ret(0);
606 } 663 }
607 664
608 665
609 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { 666 void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
610 // Create a sequence of deoptimization entries. 667 // Create a sequence of deoptimization entries.
611 Label done; 668 Label done;
612 for (int i = 0; i < count(); i++) { 669 for (int i = 0; i < count(); i++) {
613 int start = masm()->pc_offset(); 670 int start = masm()->pc_offset();
614 USE(start); 671 USE(start);
615 __ push_imm32(i); 672 __k push_imm32(i);
616 __ jmp(&done); 673 __ jmp(&done);
617 ASSERT(masm()->pc_offset() - start == table_entry_size_); 674 ASSERT(masm()->pc_offset() - start == table_entry_size_);
618 } 675 }
619 __ bind(&done); 676 __ bind(&done);
620 } 677 }
621 678
679 #undef __k
680 #undef __k
622 #undef __ 681 #undef __
623 682
624 683
625 } } // namespace v8::internal 684 } } // namespace v8::internal
626 685
627 #endif // V8_TARGET_ARCH_X64 686 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698