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

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 9215010: Merge r10006, r10087 and r10126 from bleeding edge to the 3.6 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.6/
Patch Set: 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
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 26 matching lines...) Expand all
37 namespace v8 { 37 namespace v8 {
38 namespace internal { 38 namespace internal {
39 39
40 40
41 // When invoking builtins, we need to record the safepoint in the middle of 41 // When invoking builtins, we need to record the safepoint in the middle of
42 // the invoke instruction sequence generated by the macro assembler. 42 // the invoke instruction sequence generated by the macro assembler.
43 class SafepointGenerator : public CallWrapper { 43 class SafepointGenerator : public CallWrapper {
44 public: 44 public:
45 SafepointGenerator(LCodeGen* codegen, 45 SafepointGenerator(LCodeGen* codegen,
46 LPointerMap* pointers, 46 LPointerMap* pointers,
47 int deoptimization_index) 47 Safepoint::DeoptMode mode)
48 : codegen_(codegen), 48 : codegen_(codegen),
49 pointers_(pointers), 49 pointers_(pointers),
50 deoptimization_index_(deoptimization_index) {} 50 deopt_mode_(mode) {}
51 virtual ~SafepointGenerator() { } 51 virtual ~SafepointGenerator() { }
52 52
53 virtual void BeforeCall(int call_size) const {} 53 virtual void BeforeCall(int call_size) const {}
54 54
55 virtual void AfterCall() const { 55 virtual void AfterCall() const {
56 codegen_->RecordSafepoint(pointers_, deoptimization_index_); 56 codegen_->RecordSafepoint(pointers_, deopt_mode_);
57 } 57 }
58 58
59 private: 59 private:
60 LCodeGen* codegen_; 60 LCodeGen* codegen_;
61 LPointerMap* pointers_; 61 LPointerMap* pointers_;
62 int deoptimization_index_; 62 Safepoint::DeoptMode deopt_mode_;
63 }; 63 };
64 64
65 65
66 #define __ masm()-> 66 #define __ masm()->
67 67
68 bool LCodeGen::GenerateCode() { 68 bool LCodeGen::GenerateCode() {
69 HPhase phase("Code generation", chunk()); 69 HPhase phase("Code generation", chunk());
70 ASSERT(is_unused()); 70 ASSERT(is_unused());
71 status_ = GENERATING; 71 status_ = GENERATING;
72 CpuFeatures::Scope scope(SSE2); 72 CpuFeatures::Scope scope(SSE2);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 if (heap_slots > 0) { 180 if (heap_slots > 0) {
181 Comment(";;; Allocate local context"); 181 Comment(";;; Allocate local context");
182 // Argument to NewContext is the function, which is still in edi. 182 // Argument to NewContext is the function, which is still in edi.
183 __ push(edi); 183 __ push(edi);
184 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 184 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
185 FastNewContextStub stub(heap_slots); 185 FastNewContextStub stub(heap_slots);
186 __ CallStub(&stub); 186 __ CallStub(&stub);
187 } else { 187 } else {
188 __ CallRuntime(Runtime::kNewFunctionContext, 1); 188 __ CallRuntime(Runtime::kNewFunctionContext, 1);
189 } 189 }
190 RecordSafepoint(Safepoint::kNoDeoptimizationIndex); 190 RecordSafepoint(Safepoint::kNoLazyDeopt);
191 // Context is returned in both eax and esi. It replaces the context 191 // Context is returned in both eax and esi. It replaces the context
192 // passed to us. It's saved in the stack and kept live in esi. 192 // passed to us. It's saved in the stack and kept live in esi.
193 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); 193 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi);
194 194
195 // Copy parameters into context if necessary. 195 // Copy parameters into context if necessary.
196 int num_parameters = scope()->num_parameters(); 196 int num_parameters = scope()->num_parameters();
197 for (int i = 0; i < num_parameters; i++) { 197 for (int i = 0; i < num_parameters; i++) {
198 Variable* var = scope()->parameter(i); 198 Variable* var = scope()->parameter(i);
199 if (var->IsContextSlot()) { 199 if (var->IsContextSlot()) {
200 int parameter_offset = StandardFrameConstants::kCallerSPOffset + 200 int parameter_offset = StandardFrameConstants::kCallerSPOffset +
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 if (instr->IsLabel()) { 234 if (instr->IsLabel()) {
235 LLabel* label = LLabel::cast(instr); 235 LLabel* label = LLabel::cast(instr);
236 emit_instructions = !label->HasReplacement(); 236 emit_instructions = !label->HasReplacement();
237 } 237 }
238 238
239 if (emit_instructions) { 239 if (emit_instructions) {
240 Comment(";;; @%d: %s.", current_instruction_, instr->Mnemonic()); 240 Comment(";;; @%d: %s.", current_instruction_, instr->Mnemonic());
241 instr->CompileToNative(this); 241 instr->CompileToNative(this);
242 } 242 }
243 } 243 }
244 EnsureSpaceForLazyDeopt();
244 return !is_aborted(); 245 return !is_aborted();
245 } 246 }
246 247
247 248
248 LInstruction* LCodeGen::GetNextInstruction() {
249 if (current_instruction_ < instructions_->length() - 1) {
250 return instructions_->at(current_instruction_ + 1);
251 } else {
252 return NULL;
253 }
254 }
255
256
257 bool LCodeGen::GenerateDeferredCode() { 249 bool LCodeGen::GenerateDeferredCode() {
258 ASSERT(is_generating()); 250 ASSERT(is_generating());
259 if (deferred_.length() > 0) { 251 if (deferred_.length() > 0) {
260 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 252 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
261 LDeferredCode* code = deferred_[i]; 253 LDeferredCode* code = deferred_[i];
262 __ bind(code->entry()); 254 __ bind(code->entry());
263 code->Generate(); 255 code->Generate();
264 __ jmp(code->exit()); 256 __ jmp(code->exit());
265 } 257 }
266
267 // Pad code to ensure that the last piece of deferred code have
268 // room for lazy bailout.
269 while ((masm()->pc_offset() - LastSafepointEnd())
270 < Deoptimizer::patch_size()) {
271 __ nop();
272 }
273 } 258 }
274 259
275 // Deferred code is the last part of the instruction sequence. Mark 260 // Deferred code is the last part of the instruction sequence. Mark
276 // the generated code as done unless we bailed out. 261 // the generated code as done unless we bailed out.
277 if (!is_aborted()) status_ = DONE; 262 if (!is_aborted()) status_ = DONE;
278 return !is_aborted(); 263 return !is_aborted();
279 } 264 }
280 265
281 266
282 bool LCodeGen::GenerateSafepointTable() { 267 bool LCodeGen::GenerateSafepointTable() {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 } 420 }
436 421
437 422
438 void LCodeGen::CallCodeGeneric(Handle<Code> code, 423 void LCodeGen::CallCodeGeneric(Handle<Code> code,
439 RelocInfo::Mode mode, 424 RelocInfo::Mode mode,
440 LInstruction* instr, 425 LInstruction* instr,
441 SafepointMode safepoint_mode) { 426 SafepointMode safepoint_mode) {
442 ASSERT(instr != NULL); 427 ASSERT(instr != NULL);
443 LPointerMap* pointers = instr->pointer_map(); 428 LPointerMap* pointers = instr->pointer_map();
444 RecordPosition(pointers->position()); 429 RecordPosition(pointers->position());
445
446 __ call(code, mode); 430 __ call(code, mode);
447 431 RecordSafepointWithLazyDeopt(instr, safepoint_mode);
448 RegisterLazyDeoptimization(instr, safepoint_mode);
449 432
450 // Signal that we don't inline smi code before these stubs in the 433 // Signal that we don't inline smi code before these stubs in the
451 // optimizing code generator. 434 // optimizing code generator.
452 if (code->kind() == Code::BINARY_OP_IC || 435 if (code->kind() == Code::BINARY_OP_IC ||
453 code->kind() == Code::COMPARE_IC) { 436 code->kind() == Code::COMPARE_IC) {
454 __ nop(); 437 __ nop();
455 } 438 }
456 } 439 }
457 440
458 441
459 void LCodeGen::CallCode(Handle<Code> code, 442 void LCodeGen::CallCode(Handle<Code> code,
460 RelocInfo::Mode mode, 443 RelocInfo::Mode mode,
461 LInstruction* instr) { 444 LInstruction* instr) {
462 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); 445 CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
463 } 446 }
464 447
465 448
466 void LCodeGen::CallRuntime(const Runtime::Function* fun, 449 void LCodeGen::CallRuntime(const Runtime::Function* fun,
467 int argc, 450 int argc,
468 LInstruction* instr) { 451 LInstruction* instr) {
469 ASSERT(instr != NULL); 452 ASSERT(instr != NULL);
470 ASSERT(instr->HasPointerMap()); 453 ASSERT(instr->HasPointerMap());
471 LPointerMap* pointers = instr->pointer_map(); 454 LPointerMap* pointers = instr->pointer_map();
472 RecordPosition(pointers->position()); 455 RecordPosition(pointers->position());
473 456
474 __ CallRuntime(fun, argc); 457 __ CallRuntime(fun, argc);
475 458
476 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); 459 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
477 } 460 }
478 461
479 462
480 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, 463 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,
481 int argc, 464 int argc,
482 LInstruction* instr, 465 LInstruction* instr,
483 LOperand* context) { 466 LOperand* context) {
484 ASSERT(context->IsRegister() || context->IsStackSlot()); 467 ASSERT(context->IsRegister() || context->IsStackSlot());
485 if (context->IsRegister()) { 468 if (context->IsRegister()) {
486 if (!ToRegister(context).is(esi)) { 469 if (!ToRegister(context).is(esi)) {
487 __ mov(esi, ToRegister(context)); 470 __ mov(esi, ToRegister(context));
488 } 471 }
489 } else { 472 } else {
490 // Context is stack slot. 473 // Context is stack slot.
491 __ mov(esi, ToOperand(context)); 474 __ mov(esi, ToOperand(context));
492 } 475 }
493 476
494 __ CallRuntimeSaveDoubles(id); 477 __ CallRuntimeSaveDoubles(id);
495 RecordSafepointWithRegisters( 478 RecordSafepointWithRegisters(
496 instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); 479 instr->pointer_map(), argc, Safepoint::kNoLazyDeopt);
497 } 480 }
498 481
499 482
500 void LCodeGen::RegisterLazyDeoptimization(LInstruction* instr, 483 void LCodeGen::RegisterEnvironmentForDeoptimization(
501 SafepointMode safepoint_mode) { 484 LEnvironment* environment, Safepoint::DeoptMode mode) {
502 // Create the environment to bailout to. If the call has side effects
503 // execution has to continue after the call otherwise execution can continue
504 // from a previous bailout point repeating the call.
505 LEnvironment* deoptimization_environment;
506 if (instr->HasDeoptimizationEnvironment()) {
507 deoptimization_environment = instr->deoptimization_environment();
508 } else {
509 deoptimization_environment = instr->environment();
510 }
511
512 RegisterEnvironmentForDeoptimization(deoptimization_environment);
513 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
514 RecordSafepoint(instr->pointer_map(),
515 deoptimization_environment->deoptimization_index());
516 } else {
517 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
518 RecordSafepointWithRegisters(
519 instr->pointer_map(),
520 0,
521 deoptimization_environment->deoptimization_index());
522 }
523 }
524
525
526 void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment) {
527 if (!environment->HasBeenRegistered()) { 485 if (!environment->HasBeenRegistered()) {
528 // Physical stack frame layout: 486 // Physical stack frame layout:
529 // -x ............. -4 0 ..................................... y 487 // -x ............. -4 0 ..................................... y
530 // [incoming arguments] [spill slots] [pushed outgoing arguments] 488 // [incoming arguments] [spill slots] [pushed outgoing arguments]
531 489
532 // Layout of the environment: 490 // Layout of the environment:
533 // 0 ..................................................... size-1 491 // 0 ..................................................... size-1
534 // [parameters] [locals] [expression stack including arguments] 492 // [parameters] [locals] [expression stack including arguments]
535 493
536 // Layout of the translation: 494 // Layout of the translation:
537 // 0 ........................................................ size - 1 + 4 495 // 0 ........................................................ size - 1 + 4
538 // [expression stack including arguments] [locals] [4 words] [parameters] 496 // [expression stack including arguments] [locals] [4 words] [parameters]
539 // |>------------ translation_size ------------<| 497 // |>------------ translation_size ------------<|
540 498
541 int frame_count = 0; 499 int frame_count = 0;
542 for (LEnvironment* e = environment; e != NULL; e = e->outer()) { 500 for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
543 ++frame_count; 501 ++frame_count;
544 } 502 }
545 Translation translation(&translations_, frame_count); 503 Translation translation(&translations_, frame_count);
546 WriteTranslation(environment, &translation); 504 WriteTranslation(environment, &translation);
547 int deoptimization_index = deoptimizations_.length(); 505 int deoptimization_index = deoptimizations_.length();
548 environment->Register(deoptimization_index, translation.index()); 506 int pc_offset = masm()->pc_offset();
507 environment->Register(deoptimization_index,
508 translation.index(),
509 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
549 deoptimizations_.Add(environment); 510 deoptimizations_.Add(environment);
550 } 511 }
551 } 512 }
552 513
553 514
554 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) { 515 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
555 RegisterEnvironmentForDeoptimization(environment); 516 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
556 ASSERT(environment->HasBeenRegistered()); 517 ASSERT(environment->HasBeenRegistered());
557 int id = environment->deoptimization_index(); 518 int id = environment->deoptimization_index();
558 Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER); 519 Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER);
559 ASSERT(entry != NULL); 520 ASSERT(entry != NULL);
560 if (entry == NULL) { 521 if (entry == NULL) {
561 Abort("bailout was not prepared"); 522 Abort("bailout was not prepared");
562 return; 523 return;
563 } 524 }
564 525
565 if (FLAG_deopt_every_n_times != 0) { 526 if (FLAG_deopt_every_n_times != 0) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id())); 586 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id()));
626 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); 587 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
627 588
628 // Populate the deoptimization entries. 589 // Populate the deoptimization entries.
629 for (int i = 0; i < length; i++) { 590 for (int i = 0; i < length; i++) {
630 LEnvironment* env = deoptimizations_[i]; 591 LEnvironment* env = deoptimizations_[i];
631 data->SetAstId(i, Smi::FromInt(env->ast_id())); 592 data->SetAstId(i, Smi::FromInt(env->ast_id()));
632 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); 593 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
633 data->SetArgumentsStackHeight(i, 594 data->SetArgumentsStackHeight(i,
634 Smi::FromInt(env->arguments_stack_height())); 595 Smi::FromInt(env->arguments_stack_height()));
596 data->SetPc(i, Smi::FromInt(env->pc_offset()));
635 } 597 }
636 code->set_deoptimization_data(*data); 598 code->set_deoptimization_data(*data);
637 } 599 }
638 600
639 601
640 int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) { 602 int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {
641 int result = deoptimization_literals_.length(); 603 int result = deoptimization_literals_.length();
642 for (int i = 0; i < deoptimization_literals_.length(); ++i) { 604 for (int i = 0; i < deoptimization_literals_.length(); ++i) {
643 if (deoptimization_literals_[i].is_identical_to(literal)) return i; 605 if (deoptimization_literals_[i].is_identical_to(literal)) return i;
644 } 606 }
(...skipping 11 matching lines...) Expand all
656 for (int i = 0, length = inlined_closures->length(); 618 for (int i = 0, length = inlined_closures->length();
657 i < length; 619 i < length;
658 i++) { 620 i++) {
659 DefineDeoptimizationLiteral(inlined_closures->at(i)); 621 DefineDeoptimizationLiteral(inlined_closures->at(i));
660 } 622 }
661 623
662 inlined_function_count_ = deoptimization_literals_.length(); 624 inlined_function_count_ = deoptimization_literals_.length();
663 } 625 }
664 626
665 627
628 void LCodeGen::RecordSafepointWithLazyDeopt(
629 LInstruction* instr, SafepointMode safepoint_mode) {
630 if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
631 RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
632 } else {
633 ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
634 RecordSafepointWithRegisters(
635 instr->pointer_map(), 0, Safepoint::kLazyDeopt);
636 }
637 }
638
639
666 void LCodeGen::RecordSafepoint( 640 void LCodeGen::RecordSafepoint(
667 LPointerMap* pointers, 641 LPointerMap* pointers,
668 Safepoint::Kind kind, 642 Safepoint::Kind kind,
669 int arguments, 643 int arguments,
670 int deoptimization_index) { 644 Safepoint::DeoptMode deopt_mode) {
671 ASSERT(kind == expected_safepoint_kind_); 645 ASSERT(kind == expected_safepoint_kind_);
672 const ZoneList<LOperand*>* operands = pointers->operands(); 646 const ZoneList<LOperand*>* operands = pointers->operands();
673 Safepoint safepoint = safepoints_.DefineSafepoint(masm(), 647 Safepoint safepoint =
674 kind, arguments, deoptimization_index); 648 safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode);
675 for (int i = 0; i < operands->length(); i++) { 649 for (int i = 0; i < operands->length(); i++) {
676 LOperand* pointer = operands->at(i); 650 LOperand* pointer = operands->at(i);
677 if (pointer->IsStackSlot()) { 651 if (pointer->IsStackSlot()) {
678 safepoint.DefinePointerSlot(pointer->index()); 652 safepoint.DefinePointerSlot(pointer->index());
679 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) { 653 } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
680 safepoint.DefinePointerRegister(ToRegister(pointer)); 654 safepoint.DefinePointerRegister(ToRegister(pointer));
681 } 655 }
682 } 656 }
683 } 657 }
684 658
685 659
686 void LCodeGen::RecordSafepoint(LPointerMap* pointers, 660 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
687 int deoptimization_index) { 661 Safepoint::DeoptMode mode) {
688 RecordSafepoint(pointers, Safepoint::kSimple, 0, deoptimization_index); 662 RecordSafepoint(pointers, Safepoint::kSimple, 0, mode);
689 } 663 }
690 664
691 665
692 void LCodeGen::RecordSafepoint(int deoptimization_index) { 666 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode mode) {
693 LPointerMap empty_pointers(RelocInfo::kNoPosition); 667 LPointerMap empty_pointers(RelocInfo::kNoPosition);
694 RecordSafepoint(&empty_pointers, deoptimization_index); 668 RecordSafepoint(&empty_pointers, mode);
695 } 669 }
696 670
697 671
698 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, 672 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
699 int arguments, 673 int arguments,
700 int deoptimization_index) { 674 Safepoint::DeoptMode mode) {
701 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, 675 RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, mode);
702 deoptimization_index);
703 } 676 }
704 677
705 678
706 void LCodeGen::RecordPosition(int position) { 679 void LCodeGen::RecordPosition(int position) {
707 if (position == RelocInfo::kNoPosition) return; 680 if (position == RelocInfo::kNoPosition) return;
708 masm()->positions_recorder()->RecordPosition(position); 681 masm()->positions_recorder()->RecordPosition(position);
709 } 682 }
710 683
711 684
712 void LCodeGen::DoLabel(LLabel* label) { 685 void LCodeGen::DoLabel(LLabel* label) {
(...skipping 14 matching lines...) Expand all
727 700
728 701
729 void LCodeGen::DoGap(LGap* gap) { 702 void LCodeGen::DoGap(LGap* gap) {
730 for (int i = LGap::FIRST_INNER_POSITION; 703 for (int i = LGap::FIRST_INNER_POSITION;
731 i <= LGap::LAST_INNER_POSITION; 704 i <= LGap::LAST_INNER_POSITION;
732 i++) { 705 i++) {
733 LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i); 706 LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i);
734 LParallelMove* move = gap->GetParallelMove(inner_pos); 707 LParallelMove* move = gap->GetParallelMove(inner_pos);
735 if (move != NULL) DoParallelMove(move); 708 if (move != NULL) DoParallelMove(move);
736 } 709 }
737
738 LInstruction* next = GetNextInstruction();
739 if (next != NULL && next->IsLazyBailout()) {
740 int pc = masm()->pc_offset();
741 safepoints_.SetPcAfterGap(pc);
742 }
743 } 710 }
744 711
745 712
746 void LCodeGen::DoInstructionGap(LInstructionGap* instr) { 713 void LCodeGen::DoInstructionGap(LInstructionGap* instr) {
747 DoGap(instr); 714 DoGap(instr);
748 } 715 }
749 716
750 717
751 void LCodeGen::DoParameter(LParameter* instr) { 718 void LCodeGen::DoParameter(LParameter* instr) {
752 // Nothing to do. 719 // Nothing to do.
(...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 } 1809 }
1843 1810
1844 1811
1845 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { 1812 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
1846 class DeferredInstanceOfKnownGlobal: public LDeferredCode { 1813 class DeferredInstanceOfKnownGlobal: public LDeferredCode {
1847 public: 1814 public:
1848 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, 1815 DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
1849 LInstanceOfKnownGlobal* instr) 1816 LInstanceOfKnownGlobal* instr)
1850 : LDeferredCode(codegen), instr_(instr) { } 1817 : LDeferredCode(codegen), instr_(instr) { }
1851 virtual void Generate() { 1818 virtual void Generate() {
1852 codegen()->DoDeferredLInstanceOfKnownGlobal(instr_, &map_check_); 1819 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
1853 } 1820 }
1854 1821
1855 Label* map_check() { return &map_check_; } 1822 Label* map_check() { return &map_check_; }
1856 1823
1857 private: 1824 private:
1858 LInstanceOfKnownGlobal* instr_; 1825 LInstanceOfKnownGlobal* instr_;
1859 Label map_check_; 1826 Label map_check_;
1860 }; 1827 };
1861 1828
1862 DeferredInstanceOfKnownGlobal* deferred; 1829 DeferredInstanceOfKnownGlobal* deferred;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1898 __ bind(&false_result); 1865 __ bind(&false_result);
1899 __ mov(ToRegister(instr->result()), factory()->false_value()); 1866 __ mov(ToRegister(instr->result()), factory()->false_value());
1900 1867
1901 // Here result has either true or false. Deferred code also produces true or 1868 // Here result has either true or false. Deferred code also produces true or
1902 // false object. 1869 // false object.
1903 __ bind(deferred->exit()); 1870 __ bind(deferred->exit());
1904 __ bind(&done); 1871 __ bind(&done);
1905 } 1872 }
1906 1873
1907 1874
1908 void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, 1875 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
1909 Label* map_check) { 1876 Label* map_check) {
1910 PushSafepointRegistersScope scope(this); 1877 PushSafepointRegistersScope scope(this);
1911 1878
1912 InstanceofStub::Flags flags = InstanceofStub::kNoFlags; 1879 InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
1913 flags = static_cast<InstanceofStub::Flags>( 1880 flags = static_cast<InstanceofStub::Flags>(
1914 flags | InstanceofStub::kArgsInRegisters); 1881 flags | InstanceofStub::kArgsInRegisters);
1915 flags = static_cast<InstanceofStub::Flags>( 1882 flags = static_cast<InstanceofStub::Flags>(
1916 flags | InstanceofStub::kCallSiteInlineCheck); 1883 flags | InstanceofStub::kCallSiteInlineCheck);
1917 flags = static_cast<InstanceofStub::Flags>( 1884 flags = static_cast<InstanceofStub::Flags>(
1918 flags | InstanceofStub::kReturnTrueFalseObject); 1885 flags | InstanceofStub::kReturnTrueFalseObject);
1919 InstanceofStub stub(flags); 1886 InstanceofStub stub(flags);
1920 1887
1921 // Get the temp register reserved by the instruction. This needs to be a 1888 // Get the temp register reserved by the instruction. This needs to be a
1922 // register which is pushed last by PushSafepointRegisters as top of the 1889 // register which is pushed last by PushSafepointRegisters as top of the
1923 // stack is used to pass the offset to the location of the map check to 1890 // stack is used to pass the offset to the location of the map check to
1924 // the stub. 1891 // the stub.
1925 Register temp = ToRegister(instr->TempAt(0)); 1892 Register temp = ToRegister(instr->TempAt(0));
1926 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); 1893 ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0);
1927 __ mov(InstanceofStub::right(), Immediate(instr->function())); 1894 __ mov(InstanceofStub::right(), Immediate(instr->function()));
1928 static const int kAdditionalDelta = 13; 1895 static const int kAdditionalDelta = 13;
1929 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; 1896 int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
1930 __ mov(temp, Immediate(delta)); 1897 __ mov(temp, Immediate(delta));
1931 __ StoreToSafepointRegisterSlot(temp, temp); 1898 __ StoreToSafepointRegisterSlot(temp, temp);
1932 CallCodeGeneric(stub.GetCode(), 1899 CallCodeGeneric(stub.GetCode(),
1933 RelocInfo::CODE_TARGET, 1900 RelocInfo::CODE_TARGET,
1934 instr, 1901 instr,
1935 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 1902 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
1903 ASSERT(instr->HasDeoptimizationEnvironment());
1904 LEnvironment* env = instr->deoptimization_environment();
1905 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
1906
1936 // Put the result value into the eax slot and restore all registers. 1907 // Put the result value into the eax slot and restore all registers.
1937 __ StoreToSafepointRegisterSlot(eax, eax); 1908 __ StoreToSafepointRegisterSlot(eax, eax);
1938 } 1909 }
1939 1910
1940 1911
1941 static Condition ComputeCompareCondition(Token::Value op) { 1912 static Condition ComputeCompareCondition(Token::Value op) {
1942 switch (op) { 1913 switch (op) {
1943 case Token::EQ_STRICT: 1914 case Token::EQ_STRICT:
1944 case Token::EQ: 1915 case Token::EQ:
1945 return equal; 1916 return equal;
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
2495 __ j(zero, &invoke, Label::kNear); 2466 __ j(zero, &invoke, Label::kNear);
2496 __ bind(&loop); 2467 __ bind(&loop);
2497 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize)); 2468 __ push(Operand(elements, length, times_pointer_size, 1 * kPointerSize));
2498 __ dec(length); 2469 __ dec(length);
2499 __ j(not_zero, &loop); 2470 __ j(not_zero, &loop);
2500 2471
2501 // Invoke the function. 2472 // Invoke the function.
2502 __ bind(&invoke); 2473 __ bind(&invoke);
2503 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 2474 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
2504 LPointerMap* pointers = instr->pointer_map(); 2475 LPointerMap* pointers = instr->pointer_map();
2505 LEnvironment* env = instr->deoptimization_environment();
2506 RecordPosition(pointers->position()); 2476 RecordPosition(pointers->position());
2507 RegisterEnvironmentForDeoptimization(env); 2477 SafepointGenerator safepoint_generator(
2508 SafepointGenerator safepoint_generator(this, 2478 this, pointers, Safepoint::kLazyDeopt);
2509 pointers,
2510 env->deoptimization_index());
2511 ParameterCount actual(eax); 2479 ParameterCount actual(eax);
2512 __ InvokeFunction(function, actual, CALL_FUNCTION, 2480 __ InvokeFunction(function, actual, CALL_FUNCTION,
2513 safepoint_generator, CALL_AS_METHOD); 2481 safepoint_generator, CALL_AS_METHOD);
2514 } 2482 }
2515 2483
2516 2484
2517 void LCodeGen::DoPushArgument(LPushArgument* instr) { 2485 void LCodeGen::DoPushArgument(LPushArgument* instr) {
2518 LOperand* argument = instr->InputAt(0); 2486 LOperand* argument = instr->InputAt(0);
2519 if (argument->IsConstantOperand()) { 2487 if (argument->IsConstantOperand()) {
2520 __ push(ToImmediate(argument)); 2488 __ push(ToImmediate(argument));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 RecordPosition(pointers->position()); 2551 RecordPosition(pointers->position());
2584 2552
2585 // Invoke function. 2553 // Invoke function.
2586 __ SetCallKind(ecx, call_kind); 2554 __ SetCallKind(ecx, call_kind);
2587 if (*function == *info()->closure()) { 2555 if (*function == *info()->closure()) {
2588 __ CallSelf(); 2556 __ CallSelf();
2589 } else { 2557 } else {
2590 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset)); 2558 __ call(FieldOperand(edi, JSFunction::kCodeEntryOffset));
2591 } 2559 }
2592 2560
2593 // Setup deoptimization. 2561 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
2594 RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT);
2595 } 2562 }
2596 2563
2597 2564
2598 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 2565 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
2599 ASSERT(ToRegister(instr->result()).is(eax)); 2566 ASSERT(ToRegister(instr->result()).is(eax));
2600 __ mov(edi, instr->function()); 2567 __ mov(edi, instr->function());
2601 CallKnownFunction(instr->function(), 2568 CallKnownFunction(instr->function(),
2602 instr->arity(), 2569 instr->arity(),
2603 instr, 2570 instr,
2604 CALL_AS_METHOD); 2571 CALL_AS_METHOD);
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2959 } 2926 }
2960 } 2927 }
2961 2928
2962 2929
2963 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 2930 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
2964 ASSERT(ToRegister(instr->context()).is(esi)); 2931 ASSERT(ToRegister(instr->context()).is(esi));
2965 ASSERT(ToRegister(instr->function()).is(edi)); 2932 ASSERT(ToRegister(instr->function()).is(edi));
2966 ASSERT(instr->HasPointerMap()); 2933 ASSERT(instr->HasPointerMap());
2967 ASSERT(instr->HasDeoptimizationEnvironment()); 2934 ASSERT(instr->HasDeoptimizationEnvironment());
2968 LPointerMap* pointers = instr->pointer_map(); 2935 LPointerMap* pointers = instr->pointer_map();
2969 LEnvironment* env = instr->deoptimization_environment();
2970 RecordPosition(pointers->position()); 2936 RecordPosition(pointers->position());
2971 RegisterEnvironmentForDeoptimization(env); 2937 SafepointGenerator generator(
2972 SafepointGenerator generator(this, pointers, env->deoptimization_index()); 2938 this, pointers, Safepoint::kLazyDeopt);
2973 ParameterCount count(instr->arity()); 2939 ParameterCount count(instr->arity());
2974 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 2940 __ InvokeFunction(edi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
2975 } 2941 }
2976 2942
2977 2943
2978 void LCodeGen::DoCallKeyed(LCallKeyed* instr) { 2944 void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
2979 ASSERT(ToRegister(instr->context()).is(esi)); 2945 ASSERT(ToRegister(instr->context()).is(esi));
2980 ASSERT(ToRegister(instr->key()).is(ecx)); 2946 ASSERT(ToRegister(instr->key()).is(ecx));
2981 ASSERT(ToRegister(instr->result()).is(eax)); 2947 ASSERT(ToRegister(instr->result()).is(eax));
2982 2948
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
3456 // integer value. 3422 // integer value.
3457 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); 3423 __ StoreToSafepointRegisterSlot(reg, Immediate(0));
3458 // NumberTagI and NumberTagD use the context from the frame, rather than 3424 // NumberTagI and NumberTagD use the context from the frame, rather than
3459 // the environment's HContext or HInlinedContext value. 3425 // the environment's HContext or HInlinedContext value.
3460 // They only call Runtime::kAllocateHeapNumber. 3426 // They only call Runtime::kAllocateHeapNumber.
3461 // The corresponding HChange instructions are added in a phase that does 3427 // The corresponding HChange instructions are added in a phase that does
3462 // not have easy access to the local context. 3428 // not have easy access to the local context.
3463 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3429 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3464 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3430 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
3465 RecordSafepointWithRegisters( 3431 RecordSafepointWithRegisters(
3466 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); 3432 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
3467 if (!reg.is(eax)) __ mov(reg, eax); 3433 if (!reg.is(eax)) __ mov(reg, eax);
3468 3434
3469 // Done. Put the value in xmm0 into the value of the allocated heap 3435 // Done. Put the value in xmm0 into the value of the allocated heap
3470 // number. 3436 // number.
3471 __ bind(&done); 3437 __ bind(&done);
3472 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); 3438 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0);
3473 __ StoreToSafepointRegisterSlot(reg, reg); 3439 __ StoreToSafepointRegisterSlot(reg, reg);
3474 } 3440 }
3475 3441
3476 3442
(...skipping 30 matching lines...) Expand all
3507 __ Set(reg, Immediate(0)); 3473 __ Set(reg, Immediate(0));
3508 3474
3509 PushSafepointRegistersScope scope(this); 3475 PushSafepointRegistersScope scope(this);
3510 // NumberTagI and NumberTagD use the context from the frame, rather than 3476 // NumberTagI and NumberTagD use the context from the frame, rather than
3511 // the environment's HContext or HInlinedContext value. 3477 // the environment's HContext or HInlinedContext value.
3512 // They only call Runtime::kAllocateHeapNumber. 3478 // They only call Runtime::kAllocateHeapNumber.
3513 // The corresponding HChange instructions are added in a phase that does 3479 // The corresponding HChange instructions are added in a phase that does
3514 // not have easy access to the local context. 3480 // not have easy access to the local context.
3515 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 3481 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
3516 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 3482 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
3517 RecordSafepointWithRegisters(instr->pointer_map(), 0, 3483 RecordSafepointWithRegisters(
3518 Safepoint::kNoDeoptimizationIndex); 3484 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
3519 __ StoreToSafepointRegisterSlot(reg, eax); 3485 __ StoreToSafepointRegisterSlot(reg, eax);
3520 } 3486 }
3521 3487
3522 3488
3523 void LCodeGen::DoSmiTag(LSmiTag* instr) { 3489 void LCodeGen::DoSmiTag(LSmiTag* instr) {
3524 LOperand* input = instr->InputAt(0); 3490 LOperand* input = instr->InputAt(0);
3525 ASSERT(input->IsRegister() && input->Equals(instr->result())); 3491 ASSERT(input->IsRegister() && input->Equals(instr->result()));
3526 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); 3492 ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow));
3527 __ SmiTag(ToRegister(input)); 3493 __ SmiTag(ToRegister(input));
3528 } 3494 }
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
4239 __ j(not_equal, &check_frame_marker, Label::kNear); 4205 __ j(not_equal, &check_frame_marker, Label::kNear);
4240 __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); 4206 __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset));
4241 4207
4242 // Check the marker in the calling frame. 4208 // Check the marker in the calling frame.
4243 __ bind(&check_frame_marker); 4209 __ bind(&check_frame_marker);
4244 __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), 4210 __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset),
4245 Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); 4211 Immediate(Smi::FromInt(StackFrame::CONSTRUCT)));
4246 } 4212 }
4247 4213
4248 4214
4215 void LCodeGen::EnsureSpaceForLazyDeopt() {
4216 // Ensure that we have enough space after the previous lazy-bailout
4217 // instruction for patching the code here.
4218 int current_pc = masm()->pc_offset();
4219 int patch_size = Deoptimizer::patch_size();
4220 if (current_pc < last_lazy_deopt_pc_ + patch_size) {
4221 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
4222 while (padding_size-- > 0) {
4223 __ nop();
4224 }
4225 }
4226 last_lazy_deopt_pc_ = masm()->pc_offset();
4227 }
4228
4229
4249 void LCodeGen::DoLazyBailout(LLazyBailout* instr) { 4230 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
4250 // No code for lazy bailout instruction. Used to capture environment after a 4231 EnsureSpaceForLazyDeopt();
4251 // call for populating the safepoint data with deoptimization data. 4232 ASSERT(instr->HasEnvironment());
4233 LEnvironment* env = instr->environment();
4234 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4235 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
4252 } 4236 }
4253 4237
4254 4238
4255 void LCodeGen::DoDeoptimize(LDeoptimize* instr) { 4239 void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
4256 DeoptimizeIf(no_condition, instr->environment()); 4240 DeoptimizeIf(no_condition, instr->environment());
4257 } 4241 }
4258 4242
4259 4243
4260 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { 4244 void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) {
4261 LOperand* obj = instr->object(); 4245 LOperand* obj = instr->object();
4262 LOperand* key = instr->key(); 4246 LOperand* key = instr->key();
4263 __ push(ToOperand(obj)); 4247 __ push(ToOperand(obj));
4264 if (key->IsConstantOperand()) { 4248 if (key->IsConstantOperand()) {
4265 __ push(ToImmediate(key)); 4249 __ push(ToImmediate(key));
4266 } else { 4250 } else {
4267 __ push(ToOperand(key)); 4251 __ push(ToOperand(key));
4268 } 4252 }
4269 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 4253 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
4270 LPointerMap* pointers = instr->pointer_map(); 4254 LPointerMap* pointers = instr->pointer_map();
4271 LEnvironment* env = instr->deoptimization_environment();
4272 RecordPosition(pointers->position()); 4255 RecordPosition(pointers->position());
4273 RegisterEnvironmentForDeoptimization(env);
4274 // Create safepoint generator that will also ensure enough space in the 4256 // Create safepoint generator that will also ensure enough space in the
4275 // reloc info for patching in deoptimization (since this is invoking a 4257 // reloc info for patching in deoptimization (since this is invoking a
4276 // builtin) 4258 // builtin)
4277 SafepointGenerator safepoint_generator(this, 4259 SafepointGenerator safepoint_generator(
4278 pointers, 4260 this, pointers, Safepoint::kLazyDeopt);
4279 env->deoptimization_index());
4280 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); 4261 __ push(Immediate(Smi::FromInt(strict_mode_flag())));
4281 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); 4262 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator);
4282 } 4263 }
4283 4264
4284 4265
4285 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { 4266 void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
4286 { 4267 PushSafepointRegistersScope scope(this);
4287 PushSafepointRegistersScope scope(this); 4268 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
4288 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 4269 __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
4289 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); 4270 RecordSafepointWithLazyDeopt(
4290 RegisterLazyDeoptimization( 4271 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
4291 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); 4272 ASSERT(instr->HasEnvironment());
4292 } 4273 LEnvironment* env = instr->environment();
4293 4274 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
4294 // The gap code includes the restoring of the safepoint registers.
4295 int pc = masm()->pc_offset();
4296 safepoints_.SetPcAfterGap(pc);
4297 } 4275 }
4298 4276
4299 4277
4300 void LCodeGen::DoStackCheck(LStackCheck* instr) { 4278 void LCodeGen::DoStackCheck(LStackCheck* instr) {
4301 class DeferredStackCheck: public LDeferredCode { 4279 class DeferredStackCheck: public LDeferredCode {
4302 public: 4280 public:
4303 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) 4281 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
4304 : LDeferredCode(codegen), instr_(instr) { } 4282 : LDeferredCode(codegen), instr_(instr) { }
4305 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); } 4283 virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
4306 private: 4284 private:
4307 LStackCheck* instr_; 4285 LStackCheck* instr_;
4308 }; 4286 };
4309 4287
4288 ASSERT(instr->HasEnvironment());
4289 LEnvironment* env = instr->environment();
4290 // There is no LLazyBailout instruction for stack-checks. We have to
4291 // prepare for lazy deoptimization explicitly here.
4310 if (instr->hydrogen()->is_function_entry()) { 4292 if (instr->hydrogen()->is_function_entry()) {
4311 // Perform stack overflow check. 4293 // Perform stack overflow check.
4312 Label done; 4294 Label done;
4313 ExternalReference stack_limit = 4295 ExternalReference stack_limit =
4314 ExternalReference::address_of_stack_limit(isolate()); 4296 ExternalReference::address_of_stack_limit(isolate());
4315 __ cmp(esp, Operand::StaticVariable(stack_limit)); 4297 __ cmp(esp, Operand::StaticVariable(stack_limit));
4316 __ j(above_equal, &done, Label::kNear); 4298 __ j(above_equal, &done, Label::kNear);
4317 4299
4318 ASSERT(instr->context()->IsRegister()); 4300 ASSERT(instr->context()->IsRegister());
4319 ASSERT(ToRegister(instr->context()).is(esi)); 4301 ASSERT(ToRegister(instr->context()).is(esi));
4320 StackCheckStub stub; 4302 StackCheckStub stub;
4321 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 4303 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
4304 EnsureSpaceForLazyDeopt();
4322 __ bind(&done); 4305 __ bind(&done);
4306 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4307 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
4323 } else { 4308 } else {
4324 ASSERT(instr->hydrogen()->is_backwards_branch()); 4309 ASSERT(instr->hydrogen()->is_backwards_branch());
4325 // Perform stack overflow check if this goto needs it before jumping. 4310 // Perform stack overflow check if this goto needs it before jumping.
4326 DeferredStackCheck* deferred_stack_check = 4311 DeferredStackCheck* deferred_stack_check =
4327 new DeferredStackCheck(this, instr); 4312 new DeferredStackCheck(this, instr);
4328 ExternalReference stack_limit = 4313 ExternalReference stack_limit =
4329 ExternalReference::address_of_stack_limit(isolate()); 4314 ExternalReference::address_of_stack_limit(isolate());
4330 __ cmp(esp, Operand::StaticVariable(stack_limit)); 4315 __ cmp(esp, Operand::StaticVariable(stack_limit));
4331 __ j(below, deferred_stack_check->entry()); 4316 __ j(below, deferred_stack_check->entry());
4317 EnsureSpaceForLazyDeopt();
4332 __ bind(instr->done_label()); 4318 __ bind(instr->done_label());
4333 deferred_stack_check->SetExit(instr->done_label()); 4319 deferred_stack_check->SetExit(instr->done_label());
4320 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
4321 // Don't record a deoptimization index for the safepoint here.
4322 // This will be done explicitly when emitting call and the safepoint in
4323 // the deferred code.
4334 } 4324 }
4335 } 4325 }
4336 4326
4337 4327
4338 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 4328 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
4339 // This is a pseudo-instruction that ensures that the environment here is 4329 // This is a pseudo-instruction that ensures that the environment here is
4340 // properly registered for deoptimization and records the assembler's PC 4330 // properly registered for deoptimization and records the assembler's PC
4341 // offset. 4331 // offset.
4342 LEnvironment* environment = instr->environment(); 4332 LEnvironment* environment = instr->environment();
4343 environment->SetSpilledRegisters(instr->SpilledRegisterArray(), 4333 environment->SetSpilledRegisters(instr->SpilledRegisterArray(),
4344 instr->SpilledDoubleRegisterArray()); 4334 instr->SpilledDoubleRegisterArray());
4345 4335
4346 // If the environment were already registered, we would have no way of 4336 // If the environment were already registered, we would have no way of
4347 // backpatching it with the spill slot operands. 4337 // backpatching it with the spill slot operands.
4348 ASSERT(!environment->HasBeenRegistered()); 4338 ASSERT(!environment->HasBeenRegistered());
4349 RegisterEnvironmentForDeoptimization(environment); 4339 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
4350 ASSERT(osr_pc_offset_ == -1); 4340 ASSERT(osr_pc_offset_ == -1);
4351 osr_pc_offset_ = masm()->pc_offset(); 4341 osr_pc_offset_ = masm()->pc_offset();
4352 } 4342 }
4353 4343
4354 4344
4355 void LCodeGen::DoIn(LIn* instr) { 4345 void LCodeGen::DoIn(LIn* instr) {
4356 LOperand* obj = instr->object(); 4346 LOperand* obj = instr->object();
4357 LOperand* key = instr->key(); 4347 LOperand* key = instr->key();
4358 if (key->IsConstantOperand()) { 4348 if (key->IsConstantOperand()) {
4359 __ push(ToImmediate(key)); 4349 __ push(ToImmediate(key));
4360 } else { 4350 } else {
4361 __ push(ToOperand(key)); 4351 __ push(ToOperand(key));
4362 } 4352 }
4363 if (obj->IsConstantOperand()) { 4353 if (obj->IsConstantOperand()) {
4364 __ push(ToImmediate(obj)); 4354 __ push(ToImmediate(obj));
4365 } else { 4355 } else {
4366 __ push(ToOperand(obj)); 4356 __ push(ToOperand(obj));
4367 } 4357 }
4368 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment()); 4358 ASSERT(instr->HasPointerMap() && instr->HasDeoptimizationEnvironment());
4369 LPointerMap* pointers = instr->pointer_map(); 4359 LPointerMap* pointers = instr->pointer_map();
4370 LEnvironment* env = instr->deoptimization_environment();
4371 RecordPosition(pointers->position()); 4360 RecordPosition(pointers->position());
4372 RegisterEnvironmentForDeoptimization(env); 4361 SafepointGenerator safepoint_generator(
4373 // Create safepoint generator that will also ensure enough space in the 4362 this, pointers, Safepoint::kLazyDeopt);
4374 // reloc info for patching in deoptimization (since this is invoking a
4375 // builtin)
4376 SafepointGenerator safepoint_generator(this,
4377 pointers,
4378 env->deoptimization_index());
4379 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4363 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4380 } 4364 }
4381 4365
4382 4366
4383 #undef __ 4367 #undef __
4384 4368
4385 } } // namespace v8::internal 4369 } } // namespace v8::internal
4386 4370
4387 #endif // V8_TARGET_ARCH_IA32 4371 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698