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

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

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 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/arm/debug-arm.cc ('k') | src/arm/frames-arm.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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 // Destroy the code which is not supposed to be run again. 105 // Destroy the code which is not supposed to be run again.
106 int instructions = 106 int instructions =
107 (code->safepoint_table_offset() - last_pc_offset) / Assembler::kInstrSize; 107 (code->safepoint_table_offset() - last_pc_offset) / Assembler::kInstrSize;
108 CodePatcher destroyer(code->instruction_start() + last_pc_offset, 108 CodePatcher destroyer(code->instruction_start() + last_pc_offset,
109 instructions); 109 instructions);
110 for (int x = 0; x < instructions; x++) { 110 for (int x = 0; x < instructions; x++) {
111 destroyer.masm()->bkpt(0); 111 destroyer.masm()->bkpt(0);
112 } 112 }
113 #endif 113 #endif
114 114
115 Isolate* isolate = code->GetIsolate();
116
115 // Add the deoptimizing code to the list. 117 // Add the deoptimizing code to the list.
116 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code); 118 DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
117 DeoptimizerData* data = code->GetIsolate()->deoptimizer_data(); 119 DeoptimizerData* data = isolate->deoptimizer_data();
118 node->set_next(data->deoptimizing_code_list_); 120 node->set_next(data->deoptimizing_code_list_);
119 data->deoptimizing_code_list_ = node; 121 data->deoptimizing_code_list_ = node;
120 122
123 // We might be in the middle of incremental marking with compaction.
124 // Tell collector to treat this code object in a special way and
125 // ignore all slots that might have been recorded on it.
126 isolate->heap()->mark_compact_collector()->InvalidateCode(code);
127
121 // Set the code for the function to non-optimized version. 128 // Set the code for the function to non-optimized version.
122 function->ReplaceCode(function->shared()->code()); 129 function->ReplaceCode(function->shared()->code());
123 130
124 if (FLAG_trace_deopt) { 131 if (FLAG_trace_deopt) {
125 PrintF("[forced deoptimization: "); 132 PrintF("[forced deoptimization: ");
126 function->PrintName(); 133 function->PrintName();
127 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function)); 134 PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function));
128 #ifdef DEBUG 135 #ifdef DEBUG
129 if (FLAG_print_code) { 136 if (FLAG_print_code) {
130 code->PrintLn(); 137 code->PrintLn();
131 } 138 }
132 #endif 139 #endif
133 } 140 }
134 } 141 }
135 142
136 143
137 void Deoptimizer::PatchStackCheckCodeAt(Address pc_after, 144 void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code,
145 Address pc_after,
138 Code* check_code, 146 Code* check_code,
139 Code* replacement_code) { 147 Code* replacement_code) {
140 const int kInstrSize = Assembler::kInstrSize; 148 const int kInstrSize = Assembler::kInstrSize;
141 // The call of the stack guard check has the following form: 149 // The call of the stack guard check has the following form:
142 // e1 5d 00 0c cmp sp, <limit> 150 // e1 5d 00 0c cmp sp, <limit>
143 // 2a 00 00 01 bcs ok 151 // 2a 00 00 01 bcs ok
144 // e5 9f c? ?? ldr ip, [pc, <stack guard address>] 152 // e5 9f c? ?? ldr ip, [pc, <stack guard address>]
145 // e1 2f ff 3c blx ip 153 // e1 2f ff 3c blx ip
146 ASSERT(Memory::int32_at(pc_after - kInstrSize) == 154 ASSERT(Memory::int32_at(pc_after - kInstrSize) ==
147 (al | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | ip.code())); 155 (al | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | ip.code()));
(...skipping 14 matching lines...) Expand all
162 170
163 // Replace the stack check address in the constant pool 171 // Replace the stack check address in the constant pool
164 // with the entry address of the replacement code. 172 // with the entry address of the replacement code.
165 uint32_t stack_check_address_offset = Memory::uint16_at(pc_after - 173 uint32_t stack_check_address_offset = Memory::uint16_at(pc_after -
166 2 * kInstrSize) & 0xfff; 174 2 * kInstrSize) & 0xfff;
167 Address stack_check_address_pointer = pc_after + stack_check_address_offset; 175 Address stack_check_address_pointer = pc_after + stack_check_address_offset;
168 ASSERT(Memory::uint32_at(stack_check_address_pointer) == 176 ASSERT(Memory::uint32_at(stack_check_address_pointer) ==
169 reinterpret_cast<uint32_t>(check_code->entry())); 177 reinterpret_cast<uint32_t>(check_code->entry()));
170 Memory::uint32_at(stack_check_address_pointer) = 178 Memory::uint32_at(stack_check_address_pointer) =
171 reinterpret_cast<uint32_t>(replacement_code->entry()); 179 reinterpret_cast<uint32_t>(replacement_code->entry());
180
181 RelocInfo rinfo(pc_after - 2 * kInstrSize,
182 RelocInfo::CODE_TARGET,
183 0,
184 unoptimized_code);
185 unoptimized_code->GetHeap()->incremental_marking()->RecordWriteIntoCode(
186 unoptimized_code, &rinfo, replacement_code);
172 } 187 }
173 188
174 189
175 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after, 190 void Deoptimizer::RevertStackCheckCodeAt(Address pc_after,
176 Code* check_code, 191 Code* check_code,
177 Code* replacement_code) { 192 Code* replacement_code) {
178 const int kInstrSize = Assembler::kInstrSize; 193 const int kInstrSize = Assembler::kInstrSize;
179 ASSERT(Memory::uint32_at(pc_after - kInstrSize) == 0xe12fff3c); 194 ASSERT(Memory::uint32_at(pc_after - kInstrSize) == 0xe12fff3c);
180 ASSERT(Memory::uint8_at(pc_after - kInstrSize - 1) == 0xe5); 195 ASSERT(Memory::uint8_at(pc_after - kInstrSize - 1) == 0xe5);
181 ASSERT(Memory::uint8_at(pc_after - kInstrSize - 2) == 0x9f); 196 ASSERT(Memory::uint8_at(pc_after - kInstrSize - 2) == 0x9f);
182 197
183 // Replace NOP with conditional jump. 198 // Replace NOP with conditional jump.
184 CodePatcher patcher(pc_after - 3 * kInstrSize, 1); 199 CodePatcher patcher(pc_after - 3 * kInstrSize, 1);
185 patcher.masm()->b(+4, cs); 200 patcher.masm()->b(+4, cs);
186 201
187 // Replace the stack check address in the constant pool 202 // Replace the stack check address in the constant pool
188 // with the entry address of the replacement code. 203 // with the entry address of the replacement code.
189 uint32_t stack_check_address_offset = Memory::uint16_at(pc_after - 204 uint32_t stack_check_address_offset = Memory::uint16_at(pc_after -
190 2 * kInstrSize) & 0xfff; 205 2 * kInstrSize) & 0xfff;
191 Address stack_check_address_pointer = pc_after + stack_check_address_offset; 206 Address stack_check_address_pointer = pc_after + stack_check_address_offset;
192 ASSERT(Memory::uint32_at(stack_check_address_pointer) == 207 ASSERT(Memory::uint32_at(stack_check_address_pointer) ==
193 reinterpret_cast<uint32_t>(replacement_code->entry())); 208 reinterpret_cast<uint32_t>(replacement_code->entry()));
194 Memory::uint32_at(stack_check_address_pointer) = 209 Memory::uint32_at(stack_check_address_pointer) =
195 reinterpret_cast<uint32_t>(check_code->entry()); 210 reinterpret_cast<uint32_t>(check_code->entry());
211
212 check_code->GetHeap()->incremental_marking()->
213 RecordCodeTargetPatch(pc_after - 2 * kInstrSize, check_code);
196 } 214 }
197 215
198 216
199 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) { 217 static int LookupBailoutId(DeoptimizationInputData* data, unsigned ast_id) {
200 ByteArray* translations = data->TranslationByteArray(); 218 ByteArray* translations = data->TranslationByteArray();
201 int length = data->DeoptCount(); 219 int length = data->DeoptCount();
202 for (int i = 0; i < length; i++) { 220 for (int i = 0; i < length; i++) {
203 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) { 221 if (static_cast<unsigned>(data->AstId(i)->value()) == ast_id) {
204 TranslationIterator it(translations, data->TranslationIndex(i)->value()); 222 TranslationIterator it(translations, data->TranslationIndex(i)->value());
205 int value = it.Next(); 223 int value = it.Next();
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 // Pass four arguments in r0 to r3 and fifth argument on stack. 643 // Pass four arguments in r0 to r3 and fifth argument on stack.
626 __ PrepareCallCFunction(6, r5); 644 __ PrepareCallCFunction(6, r5);
627 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 645 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
628 __ mov(r1, Operand(type())); // bailout type, 646 __ mov(r1, Operand(type())); // bailout type,
629 // r2: bailout id already loaded. 647 // r2: bailout id already loaded.
630 // r3: code address or 0 already loaded. 648 // r3: code address or 0 already loaded.
631 __ str(r4, MemOperand(sp, 0 * kPointerSize)); // Fp-to-sp delta. 649 __ str(r4, MemOperand(sp, 0 * kPointerSize)); // Fp-to-sp delta.
632 __ mov(r5, Operand(ExternalReference::isolate_address())); 650 __ mov(r5, Operand(ExternalReference::isolate_address()));
633 __ str(r5, MemOperand(sp, 1 * kPointerSize)); // Isolate. 651 __ str(r5, MemOperand(sp, 1 * kPointerSize)); // Isolate.
634 // Call Deoptimizer::New(). 652 // Call Deoptimizer::New().
635 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate), 6); 653 {
654 AllowExternalCallThatCantCauseGC scope(masm());
655 __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate), 6);
656 }
636 657
637 // Preserve "deoptimizer" object in register r0 and get the input 658 // Preserve "deoptimizer" object in register r0 and get the input
638 // frame descriptor pointer to r1 (deoptimizer->input_); 659 // frame descriptor pointer to r1 (deoptimizer->input_);
639 __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset())); 660 __ ldr(r1, MemOperand(r0, Deoptimizer::input_offset()));
640 661
641 // Copy core registers into FrameDescription::registers_[kNumRegisters]. 662 // Copy core registers into FrameDescription::registers_[kNumRegisters].
642 ASSERT(Register::kNumRegisters == kNumberOfRegisters); 663 ASSERT(Register::kNumRegisters == kNumberOfRegisters);
643 for (int i = 0; i < kNumberOfRegisters; i++) { 664 for (int i = 0; i < kNumberOfRegisters; i++) {
644 int offset = (i * kPointerSize) + FrameDescription::registers_offset(); 665 int offset = (i * kPointerSize) + FrameDescription::registers_offset();
645 __ ldr(r2, MemOperand(sp, i * kPointerSize)); 666 __ ldr(r2, MemOperand(sp, i * kPointerSize));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 __ str(r4, MemOperand(r3, 0)); 700 __ str(r4, MemOperand(r3, 0));
680 __ add(r3, r3, Operand(sizeof(uint32_t))); 701 __ add(r3, r3, Operand(sizeof(uint32_t)));
681 __ cmp(r2, sp); 702 __ cmp(r2, sp);
682 __ b(ne, &pop_loop); 703 __ b(ne, &pop_loop);
683 704
684 // Compute the output frame in the deoptimizer. 705 // Compute the output frame in the deoptimizer.
685 __ push(r0); // Preserve deoptimizer object across call. 706 __ push(r0); // Preserve deoptimizer object across call.
686 // r0: deoptimizer object; r1: scratch. 707 // r0: deoptimizer object; r1: scratch.
687 __ PrepareCallCFunction(1, r1); 708 __ PrepareCallCFunction(1, r1);
688 // Call Deoptimizer::ComputeOutputFrames(). 709 // Call Deoptimizer::ComputeOutputFrames().
689 __ CallCFunction( 710 {
690 ExternalReference::compute_output_frames_function(isolate), 1); 711 AllowExternalCallThatCantCauseGC scope(masm());
712 __ CallCFunction(
713 ExternalReference::compute_output_frames_function(isolate), 1);
714 }
691 __ pop(r0); // Restore deoptimizer object (class Deoptimizer). 715 __ pop(r0); // Restore deoptimizer object (class Deoptimizer).
692 716
693 // Replace the current (input) frame with the output frames. 717 // Replace the current (input) frame with the output frames.
694 Label outer_push_loop, inner_push_loop; 718 Label outer_push_loop, inner_push_loop;
695 // Outer loop state: r0 = current "FrameDescription** output_", 719 // Outer loop state: r0 = current "FrameDescription** output_",
696 // r1 = one past the last FrameDescription**. 720 // r1 = one past the last FrameDescription**.
697 __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset())); 721 __ ldr(r1, MemOperand(r0, Deoptimizer::output_count_offset()));
698 __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset())); // r0 is output_. 722 __ ldr(r0, MemOperand(r0, Deoptimizer::output_offset())); // r0 is output_.
699 __ add(r1, r0, Operand(r1, LSL, 2)); 723 __ add(r1, r0, Operand(r1, LSL, 2));
700 __ bind(&outer_push_loop); 724 __ bind(&outer_push_loop);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 __ push(ip); 789 __ push(ip);
766 __ b(&done); 790 __ b(&done);
767 ASSERT(masm()->pc_offset() - start == table_entry_size_); 791 ASSERT(masm()->pc_offset() - start == table_entry_size_);
768 } 792 }
769 __ bind(&done); 793 __ bind(&done);
770 } 794 }
771 795
772 #undef __ 796 #undef __
773 797
774 } } // namespace v8::internal 798 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/debug-arm.cc ('k') | src/arm/frames-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698