OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/linkage.h" | 8 #include "src/compiler/linkage.h" |
9 #include "src/compiler/pipeline.h" | 9 #include "src/compiler/pipeline.h" |
10 | 10 |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt); | 251 needs_frame_state ? Safepoint::kLazyDeopt : Safepoint::kNoLazyDeopt); |
252 | 252 |
253 if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) { | 253 if ((deopt & CallDescriptor::kLazyDeoptimization) != 0) { |
254 RecordLazyDeoptimizationEntry(instr, safepoint_id); | 254 RecordLazyDeoptimizationEntry(instr, safepoint_id); |
255 } | 255 } |
256 | 256 |
257 if (needs_frame_state) { | 257 if (needs_frame_state) { |
258 // If the frame state is present, it starts at argument 1 | 258 // If the frame state is present, it starts at argument 1 |
259 // (just after the code address). | 259 // (just after the code address). |
260 InstructionOperandConverter converter(this, instr); | 260 InstructionOperandConverter converter(this, instr); |
261 // Argument 1 is deoptimization id. | 261 // Deoptimization info starts at argument 1 |
262 int deoptimization_id = converter.ToConstant(instr->InputAt(1)).ToInt32(); | 262 int frame_state_offset = 1; |
263 // The actual frame state values start with argument 2. | 263 int deoptimization_id = BuildTranslation(instr, frame_state_offset); |
264 int first_state_value_offset = 2; | |
265 #if DEBUG | 264 #if DEBUG |
266 // Make sure all the values live in stack slots or they are immediates. | 265 // Make sure all the values live in stack slots or they are immediates. |
267 // (The values should not live in register because registers are clobbered | 266 // (The values should not live in register because registers are clobbered |
268 // by calls.) | 267 // by calls.) |
269 FrameStateDescriptor* descriptor = | 268 FrameStateDescriptor* descriptor = |
270 code()->GetDeoptimizationEntry(deoptimization_id); | 269 code()->GetDeoptimizationEntry(deoptimization_id); |
271 for (int i = 0; i < descriptor->size(); i++) { | 270 for (int i = 0; i < descriptor->size(); i++) { |
272 InstructionOperand* op = instr->InputAt(first_state_value_offset + i); | 271 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); |
273 CHECK(op->IsStackSlot() || op->IsImmediate()); | 272 CHECK(op->IsStackSlot() || op->IsImmediate()); |
274 } | 273 } |
275 #endif | 274 #endif |
276 BuildTranslation(instr, first_state_value_offset, deoptimization_id); | |
277 safepoints()->RecordLazyDeoptimizationIndex(deoptimization_id); | 275 safepoints()->RecordLazyDeoptimizationIndex(deoptimization_id); |
278 } | 276 } |
279 } | 277 } |
280 | 278 |
281 | 279 |
282 void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr, | 280 void CodeGenerator::RecordLazyDeoptimizationEntry(Instruction* instr, |
283 Safepoint::Id safepoint_id) { | 281 Safepoint::Id safepoint_id) { |
284 InstructionOperandConverter i(this, instr); | 282 InstructionOperandConverter i(this, instr); |
285 | 283 |
286 Label after_call; | 284 Label after_call; |
(...skipping 16 matching lines...) Expand all Loading... |
303 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { | 301 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { |
304 int result = static_cast<int>(deoptimization_literals_.size()); | 302 int result = static_cast<int>(deoptimization_literals_.size()); |
305 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { | 303 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { |
306 if (deoptimization_literals_[i].is_identical_to(literal)) return i; | 304 if (deoptimization_literals_[i].is_identical_to(literal)) return i; |
307 } | 305 } |
308 deoptimization_literals_.push_back(literal); | 306 deoptimization_literals_.push_back(literal); |
309 return result; | 307 return result; |
310 } | 308 } |
311 | 309 |
312 | 310 |
313 void CodeGenerator::BuildTranslation(Instruction* instr, | 311 int CodeGenerator::BuildTranslation(Instruction* instr, |
314 int first_argument_index, | 312 int frame_state_offset) { |
315 int deoptimization_id) { | 313 InstructionOperandConverter i(this, instr); |
| 314 int deoptimization_id = i.InputInt32(frame_state_offset); |
| 315 frame_state_offset++; |
| 316 |
316 // We should build translation only once. | 317 // We should build translation only once. |
317 DCHECK_EQ(NULL, deoptimization_states_[deoptimization_id]); | 318 DCHECK_EQ(NULL, deoptimization_states_[deoptimization_id]); |
318 | 319 |
319 FrameStateDescriptor* descriptor = | 320 FrameStateDescriptor* descriptor = |
320 code()->GetDeoptimizationEntry(deoptimization_id); | 321 code()->GetDeoptimizationEntry(deoptimization_id); |
321 Translation translation(&translations_, 1, 1, zone()); | 322 Translation translation(&translations_, 1, 1, zone()); |
322 translation.BeginJSFrame(descriptor->bailout_id(), | 323 translation.BeginJSFrame(descriptor->bailout_id(), |
323 Translation::kSelfLiteralId, | 324 Translation::kSelfLiteralId, |
324 descriptor->size() - descriptor->parameters_count()); | 325 descriptor->size() - descriptor->parameters_count()); |
325 | 326 |
326 for (int i = 0; i < descriptor->size(); i++) { | 327 for (int i = 0; i < descriptor->size(); i++) { |
327 AddTranslationForOperand(&translation, instr, | 328 AddTranslationForOperand(&translation, instr, |
328 instr->InputAt(i + first_argument_index)); | 329 instr->InputAt(i + frame_state_offset)); |
329 } | 330 } |
330 | 331 |
331 deoptimization_states_[deoptimization_id] = | 332 deoptimization_states_[deoptimization_id] = |
332 new (zone()) DeoptimizationState(translation.index()); | 333 new (zone()) DeoptimizationState(translation.index()); |
| 334 |
| 335 return deoptimization_id; |
333 } | 336 } |
334 | 337 |
335 | 338 |
336 void CodeGenerator::AddTranslationForOperand(Translation* translation, | 339 void CodeGenerator::AddTranslationForOperand(Translation* translation, |
337 Instruction* instr, | 340 Instruction* instr, |
338 InstructionOperand* op) { | 341 InstructionOperand* op) { |
339 if (op->IsStackSlot()) { | 342 if (op->IsStackSlot()) { |
340 translation->StoreStackSlot(op->index()); | 343 translation->StoreStackSlot(op->index()); |
341 } else if (op->IsDoubleStackSlot()) { | 344 } else if (op->IsDoubleStackSlot()) { |
342 translation->StoreDoubleStackSlot(op->index()); | 345 translation->StoreDoubleStackSlot(op->index()); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 } | 412 } |
410 | 413 |
411 | 414 |
412 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } | 415 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } |
413 | 416 |
414 #endif // !V8_TURBOFAN_BACKEND | 417 #endif // !V8_TURBOFAN_BACKEND |
415 | 418 |
416 } // namespace compiler | 419 } // namespace compiler |
417 } // namespace internal | 420 } // namespace internal |
418 } // namespace v8 | 421 } // namespace v8 |
OLD | NEW |