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 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
253 GetFrameStateDescriptor(instr, frame_state_offset); | 253 GetFrameStateDescriptor(instr, frame_state_offset); |
254 int pc_offset = masm()->pc_offset(); | 254 int pc_offset = masm()->pc_offset(); |
255 int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, | 255 int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, |
256 descriptor->state_combine()); | 256 descriptor->state_combine()); |
257 // If the pre-call frame state differs from the post-call one, produce the | 257 // If the pre-call frame state differs from the post-call one, produce the |
258 // pre-call frame state, too. | 258 // pre-call frame state, too. |
259 // TODO(jarin) We might want to avoid building the pre-call frame state | 259 // TODO(jarin) We might want to avoid building the pre-call frame state |
260 // because it is only used to get locals and arguments (by the debugger and | 260 // because it is only used to get locals and arguments (by the debugger and |
261 // f.arguments), and those are the same in the pre-call and post-call | 261 // f.arguments), and those are the same in the pre-call and post-call |
262 // states. | 262 // states. |
263 if (descriptor->state_combine() != kIgnoreOutput) { | 263 if (!descriptor->state_combine().IsOutputIgnored()) { |
264 deopt_state_id = | 264 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, |
265 BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput); | 265 OutputFrameStateCombine::Ignore()); |
266 } | 266 } |
267 #if DEBUG | 267 #if DEBUG |
268 // Make sure all the values live in stack slots or they are immediates. | 268 // Make sure all the values live in stack slots or they are immediates. |
269 // (The values should not live in register because registers are clobbered | 269 // (The values should not live in register because registers are clobbered |
270 // by calls.) | 270 // by calls.) |
271 for (size_t i = 0; i < descriptor->size(); i++) { | 271 for (size_t i = 0; i < descriptor->GetSize(); i++) { |
272 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); | 272 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); |
273 CHECK(op->IsStackSlot() || op->IsImmediate()); | 273 CHECK(op->IsStackSlot() || op->IsImmediate()); |
274 } | 274 } |
275 #endif | 275 #endif |
276 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); | 276 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); |
277 } | 277 } |
278 } | 278 } |
279 | 279 |
280 | 280 |
281 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { | 281 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { |
282 int result = static_cast<int>(deoptimization_literals_.size()); | 282 int result = static_cast<int>(deoptimization_literals_.size()); |
283 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { | 283 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { |
284 if (deoptimization_literals_[i].is_identical_to(literal)) return i; | 284 if (deoptimization_literals_[i].is_identical_to(literal)) return i; |
285 } | 285 } |
286 deoptimization_literals_.push_back(literal); | 286 deoptimization_literals_.push_back(literal); |
287 return result; | 287 return result; |
288 } | 288 } |
289 | 289 |
290 | 290 |
291 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( | 291 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( |
292 Instruction* instr, size_t frame_state_offset) { | 292 Instruction* instr, size_t frame_state_offset) { |
293 InstructionOperandConverter i(this, instr); | 293 InstructionOperandConverter i(this, instr); |
294 InstructionSequence::StateId state_id = InstructionSequence::StateId::FromInt( | 294 InstructionSequence::StateId state_id = InstructionSequence::StateId::FromInt( |
295 i.InputInt32(static_cast<int>(frame_state_offset))); | 295 i.InputInt32(static_cast<int>(frame_state_offset))); |
296 return code()->GetFrameStateDescriptor(state_id); | 296 return code()->GetFrameStateDescriptor(state_id); |
297 } | 297 } |
298 | 298 |
| 299 static InstructionOperand* OperandForFrameState( |
| 300 FrameStateDescriptor* descriptor, Instruction* instr, |
| 301 size_t frame_state_offset, size_t index, OutputFrameStateCombine combine) { |
| 302 DCHECK(index < descriptor->GetSize(combine)); |
| 303 switch (combine.kind()) { |
| 304 case OutputFrameStateCombine::kPushOutput: { |
| 305 DCHECK(combine.GetPushCount() <= instr->OutputCount()); |
| 306 size_t size_without_output = |
| 307 descriptor->GetSize(OutputFrameStateCombine::Ignore()); |
| 308 // If the index is past the existing stack items, return the output. |
| 309 if (index >= size_without_output) { |
| 310 return instr->OutputAt(index - size_without_output); |
| 311 } |
| 312 break; |
| 313 } |
| 314 case OutputFrameStateCombine::kPokeAt: |
| 315 size_t index_from_top = |
| 316 descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); |
| 317 if (index >= index_from_top && |
| 318 index < index_from_top + instr->OutputCount()) { |
| 319 return instr->OutputAt(index - index_from_top); |
| 320 } |
| 321 break; |
| 322 } |
| 323 return instr->InputAt(frame_state_offset + index); |
| 324 } |
| 325 |
299 | 326 |
300 void CodeGenerator::BuildTranslationForFrameStateDescriptor( | 327 void CodeGenerator::BuildTranslationForFrameStateDescriptor( |
301 FrameStateDescriptor* descriptor, Instruction* instr, | 328 FrameStateDescriptor* descriptor, Instruction* instr, |
302 Translation* translation, size_t frame_state_offset, | 329 Translation* translation, size_t frame_state_offset, |
303 OutputFrameStateCombine state_combine) { | 330 OutputFrameStateCombine state_combine) { |
304 // Outer-most state must be added to translation first. | 331 // Outer-most state must be added to translation first. |
305 if (descriptor->outer_state() != NULL) { | 332 if (descriptor->outer_state() != NULL) { |
306 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, | 333 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, |
307 translation, frame_state_offset, | 334 translation, frame_state_offset, |
308 kIgnoreOutput); | 335 OutputFrameStateCombine::Ignore()); |
309 } | 336 } |
310 | 337 |
311 int id = Translation::kSelfLiteralId; | 338 int id = Translation::kSelfLiteralId; |
312 if (!descriptor->jsfunction().is_null()) { | 339 if (!descriptor->jsfunction().is_null()) { |
313 id = DefineDeoptimizationLiteral( | 340 id = DefineDeoptimizationLiteral( |
314 Handle<Object>::cast(descriptor->jsfunction().ToHandleChecked())); | 341 Handle<Object>::cast(descriptor->jsfunction().ToHandleChecked())); |
315 } | 342 } |
316 | 343 |
317 switch (descriptor->type()) { | 344 switch (descriptor->type()) { |
318 case JS_FRAME: | 345 case JS_FRAME: |
319 translation->BeginJSFrame( | 346 translation->BeginJSFrame( |
320 descriptor->bailout_id(), id, | 347 descriptor->bailout_id(), id, |
321 static_cast<unsigned int>(descriptor->GetHeight(state_combine))); | 348 static_cast<unsigned int>(descriptor->GetSize(state_combine) - |
| 349 descriptor->parameters_count())); |
322 break; | 350 break; |
323 case ARGUMENTS_ADAPTOR: | 351 case ARGUMENTS_ADAPTOR: |
324 translation->BeginArgumentsAdaptorFrame( | 352 translation->BeginArgumentsAdaptorFrame( |
325 id, static_cast<unsigned int>(descriptor->parameters_count())); | 353 id, static_cast<unsigned int>(descriptor->parameters_count())); |
326 break; | 354 break; |
327 } | 355 } |
328 | 356 |
329 frame_state_offset += descriptor->outer_state()->GetTotalSize(); | 357 frame_state_offset += descriptor->outer_state()->GetTotalSize(); |
330 for (size_t i = 0; i < descriptor->size(); i++) { | 358 for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) { |
331 AddTranslationForOperand( | 359 InstructionOperand* op = OperandForFrameState( |
332 translation, instr, | 360 descriptor, instr, frame_state_offset, i, state_combine); |
333 instr->InputAt(static_cast<int>(frame_state_offset + i))); | 361 AddTranslationForOperand(translation, instr, op); |
334 } | |
335 | |
336 switch (state_combine) { | |
337 case kPushOutput: | |
338 DCHECK(instr->OutputCount() == 1); | |
339 AddTranslationForOperand(translation, instr, instr->OutputAt(0)); | |
340 break; | |
341 case kIgnoreOutput: | |
342 break; | |
343 } | 362 } |
344 } | 363 } |
345 | 364 |
346 | 365 |
347 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, | 366 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, |
348 size_t frame_state_offset, | 367 size_t frame_state_offset, |
349 OutputFrameStateCombine state_combine) { | 368 OutputFrameStateCombine state_combine) { |
350 FrameStateDescriptor* descriptor = | 369 FrameStateDescriptor* descriptor = |
351 GetFrameStateDescriptor(instr, frame_state_offset); | 370 GetFrameStateDescriptor(instr, frame_state_offset); |
352 frame_state_offset++; | 371 frame_state_offset++; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 } | 470 } |
452 | 471 |
453 | 472 |
454 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } | 473 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } |
455 | 474 |
456 #endif // !V8_TURBOFAN_BACKEND | 475 #endif // !V8_TURBOFAN_BACKEND |
457 | 476 |
458 } // namespace compiler | 477 } // namespace compiler |
459 } // namespace internal | 478 } // namespace internal |
460 } // namespace v8 | 479 } // namespace v8 |
OLD | NEW |