OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 | 28 |
29 // Compute the size of relocation information needed for the code | 29 // Compute the size of relocation information needed for the code |
30 // patching in Deoptimizer::DeoptimizeFunction. | 30 // patching in Deoptimizer::DeoptimizeFunction. |
31 int min_reloc_size = 0; | 31 int min_reloc_size = 0; |
32 int prev_pc_offset = 0; | 32 int prev_pc_offset = 0; |
33 DeoptimizationInputData* deopt_data = | 33 DeoptimizationInputData* deopt_data = |
34 DeoptimizationInputData::cast(code->deoptimization_data()); | 34 DeoptimizationInputData::cast(code->deoptimization_data()); |
35 for (int i = 0; i < deopt_data->DeoptCount(); i++) { | 35 for (int i = 0; i < deopt_data->DeoptCount(); i++) { |
36 int pc_offset = deopt_data->Pc(i)->value(); | 36 int pc_offset = deopt_data->Pc(i)->value(); |
37 if (pc_offset == -1) continue; | 37 if (pc_offset == -1) continue; |
38 ASSERT_GE(pc_offset, prev_pc_offset); | 38 DCHECK_GE(pc_offset, prev_pc_offset); |
39 int pc_delta = pc_offset - prev_pc_offset; | 39 int pc_delta = pc_offset - prev_pc_offset; |
40 // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes | 40 // We use RUNTIME_ENTRY reloc info which has a size of 2 bytes |
41 // if encodable with small pc delta encoding and up to 6 bytes | 41 // if encodable with small pc delta encoding and up to 6 bytes |
42 // otherwise. | 42 // otherwise. |
43 if (pc_delta <= RelocInfo::kMaxSmallPCDelta) { | 43 if (pc_delta <= RelocInfo::kMaxSmallPCDelta) { |
44 min_reloc_size += 2; | 44 min_reloc_size += 2; |
45 } else { | 45 } else { |
46 min_reloc_size += 6; | 46 min_reloc_size += 6; |
47 } | 47 } |
48 prev_pc_offset = pc_offset; | 48 prev_pc_offset = pc_offset; |
(...skipping 25 matching lines...) Expand all Loading... |
74 RelocInfoWriter reloc_info_writer( | 74 RelocInfoWriter reloc_info_writer( |
75 new_reloc->GetDataStartAddress() + padding, 0); | 75 new_reloc->GetDataStartAddress() + padding, 0); |
76 intptr_t comment_string | 76 intptr_t comment_string |
77 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); | 77 = reinterpret_cast<intptr_t>(RelocInfo::kFillerCommentString); |
78 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string, NULL); | 78 RelocInfo rinfo(0, RelocInfo::COMMENT, comment_string, NULL); |
79 for (int i = 0; i < additional_comments; ++i) { | 79 for (int i = 0; i < additional_comments; ++i) { |
80 #ifdef DEBUG | 80 #ifdef DEBUG |
81 byte* pos_before = reloc_info_writer.pos(); | 81 byte* pos_before = reloc_info_writer.pos(); |
82 #endif | 82 #endif |
83 reloc_info_writer.Write(&rinfo); | 83 reloc_info_writer.Write(&rinfo); |
84 ASSERT(RelocInfo::kMinRelocCommentSize == | 84 DCHECK(RelocInfo::kMinRelocCommentSize == |
85 pos_before - reloc_info_writer.pos()); | 85 pos_before - reloc_info_writer.pos()); |
86 } | 86 } |
87 // Replace relocation information on the code object. | 87 // Replace relocation information on the code object. |
88 code->set_relocation_info(*new_reloc); | 88 code->set_relocation_info(*new_reloc); |
89 } | 89 } |
90 } | 90 } |
91 | 91 |
92 | 92 |
93 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { | 93 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) { |
94 Address code_start_address = code->instruction_start(); | 94 Address code_start_address = code->instruction_start(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 Address call_address = code_start_address + deopt_data->Pc(i)->value(); | 139 Address call_address = code_start_address + deopt_data->Pc(i)->value(); |
140 CodePatcher patcher(call_address, patch_size()); | 140 CodePatcher patcher(call_address, patch_size()); |
141 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); | 141 Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY); |
142 patcher.masm()->call(deopt_entry, RelocInfo::NONE32); | 142 patcher.masm()->call(deopt_entry, RelocInfo::NONE32); |
143 // We use RUNTIME_ENTRY for deoptimization bailouts. | 143 // We use RUNTIME_ENTRY for deoptimization bailouts. |
144 RelocInfo rinfo(call_address + 1, // 1 after the call opcode. | 144 RelocInfo rinfo(call_address + 1, // 1 after the call opcode. |
145 RelocInfo::RUNTIME_ENTRY, | 145 RelocInfo::RUNTIME_ENTRY, |
146 reinterpret_cast<intptr_t>(deopt_entry), | 146 reinterpret_cast<intptr_t>(deopt_entry), |
147 NULL); | 147 NULL); |
148 reloc_info_writer.Write(&rinfo); | 148 reloc_info_writer.Write(&rinfo); |
149 ASSERT_GE(reloc_info_writer.pos(), | 149 DCHECK_GE(reloc_info_writer.pos(), |
150 reloc_info->address() + ByteArray::kHeaderSize); | 150 reloc_info->address() + ByteArray::kHeaderSize); |
151 ASSERT(prev_call_address == NULL || | 151 DCHECK(prev_call_address == NULL || |
152 call_address >= prev_call_address + patch_size()); | 152 call_address >= prev_call_address + patch_size()); |
153 ASSERT(call_address + patch_size() <= code->instruction_end()); | 153 DCHECK(call_address + patch_size() <= code->instruction_end()); |
154 #ifdef DEBUG | 154 #ifdef DEBUG |
155 prev_call_address = call_address; | 155 prev_call_address = call_address; |
156 #endif | 156 #endif |
157 } | 157 } |
158 | 158 |
159 // Move the relocation info to the beginning of the byte array. | 159 // Move the relocation info to the beginning of the byte array. |
160 int new_reloc_size = reloc_end_address - reloc_info_writer.pos(); | 160 int new_reloc_size = reloc_end_address - reloc_info_writer.pos(); |
161 MemMove(code->relocation_start(), reloc_info_writer.pos(), new_reloc_size); | 161 MemMove(code->relocation_start(), reloc_info_writer.pos(), new_reloc_size); |
162 | 162 |
163 // The relocation info is in place, update the size. | 163 // The relocation info is in place, update the size. |
164 reloc_info->set_length(new_reloc_size); | 164 reloc_info->set_length(new_reloc_size); |
165 | 165 |
166 // Handle the junk part after the new relocation info. We will create | 166 // Handle the junk part after the new relocation info. We will create |
167 // a non-live object in the extra space at the end of the former reloc info. | 167 // a non-live object in the extra space at the end of the former reloc info. |
168 Address junk_address = reloc_info->address() + reloc_info->Size(); | 168 Address junk_address = reloc_info->address() + reloc_info->Size(); |
169 ASSERT(junk_address <= reloc_end_address); | 169 DCHECK(junk_address <= reloc_end_address); |
170 isolate->heap()->CreateFillerObjectAt(junk_address, | 170 isolate->heap()->CreateFillerObjectAt(junk_address, |
171 reloc_end_address - junk_address); | 171 reloc_end_address - junk_address); |
172 } | 172 } |
173 | 173 |
174 | 174 |
175 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { | 175 void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
176 // Set the register values. The values are not important as there are no | 176 // Set the register values. The values are not important as there are no |
177 // callee saved registers in JavaScript frames, so all registers are | 177 // callee saved registers in JavaScript frames, so all registers are |
178 // spilled. Registers ebp and esp are set to the correct values though. | 178 // spilled. Registers ebp and esp are set to the correct values though. |
179 | 179 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 } | 211 } |
212 | 212 |
213 | 213 |
214 bool Deoptimizer::HasAlignmentPadding(JSFunction* function) { | 214 bool Deoptimizer::HasAlignmentPadding(JSFunction* function) { |
215 int parameter_count = function->shared()->formal_parameter_count() + 1; | 215 int parameter_count = function->shared()->formal_parameter_count() + 1; |
216 unsigned input_frame_size = input_->GetFrameSize(); | 216 unsigned input_frame_size = input_->GetFrameSize(); |
217 unsigned alignment_state_offset = | 217 unsigned alignment_state_offset = |
218 input_frame_size - parameter_count * kPointerSize - | 218 input_frame_size - parameter_count * kPointerSize - |
219 StandardFrameConstants::kFixedFrameSize - | 219 StandardFrameConstants::kFixedFrameSize - |
220 kPointerSize; | 220 kPointerSize; |
221 ASSERT(JavaScriptFrameConstants::kDynamicAlignmentStateOffset == | 221 DCHECK(JavaScriptFrameConstants::kDynamicAlignmentStateOffset == |
222 JavaScriptFrameConstants::kLocal0Offset); | 222 JavaScriptFrameConstants::kLocal0Offset); |
223 int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset); | 223 int32_t alignment_state = input_->GetFrameSlot(alignment_state_offset); |
224 return (alignment_state == kAlignmentPaddingPushed); | 224 return (alignment_state == kAlignmentPaddingPushed); |
225 } | 225 } |
226 | 226 |
227 | 227 |
228 #define __ masm()-> | 228 #define __ masm()-> |
229 | 229 |
230 void Deoptimizer::EntryGenerator::Generate() { | 230 void Deoptimizer::EntryGenerator::Generate() { |
231 GeneratePrologue(); | 231 GeneratePrologue(); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 | 395 |
396 | 396 |
397 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { | 397 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { |
398 // Create a sequence of deoptimization entries. | 398 // Create a sequence of deoptimization entries. |
399 Label done; | 399 Label done; |
400 for (int i = 0; i < count(); i++) { | 400 for (int i = 0; i < count(); i++) { |
401 int start = masm()->pc_offset(); | 401 int start = masm()->pc_offset(); |
402 USE(start); | 402 USE(start); |
403 __ push_imm32(i); | 403 __ push_imm32(i); |
404 __ jmp(&done); | 404 __ jmp(&done); |
405 ASSERT(masm()->pc_offset() - start == table_entry_size_); | 405 DCHECK(masm()->pc_offset() - start == table_entry_size_); |
406 } | 406 } |
407 __ bind(&done); | 407 __ bind(&done); |
408 } | 408 } |
409 | 409 |
410 | 410 |
411 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { | 411 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { |
412 SetFrameSlot(offset, value); | 412 SetFrameSlot(offset, value); |
413 } | 413 } |
414 | 414 |
415 | 415 |
416 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { | 416 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { |
417 SetFrameSlot(offset, value); | 417 SetFrameSlot(offset, value); |
418 } | 418 } |
419 | 419 |
420 | 420 |
421 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 421 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
422 // No out-of-line constant pool support. | 422 // No out-of-line constant pool support. |
423 UNREACHABLE(); | 423 UNREACHABLE(); |
424 } | 424 } |
425 | 425 |
426 | 426 |
427 #undef __ | 427 #undef __ |
428 | 428 |
429 | 429 |
430 } } // namespace v8::internal | 430 } } // namespace v8::internal |
431 | 431 |
432 #endif // V8_TARGET_ARCH_IA32 | 432 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |