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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 if (!descriptor->state_combine().IsOutputIgnored()) { | 263 if (!descriptor->state_combine().IsOutputIgnored()) { |
264 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, | 264 deopt_state_id = BuildTranslation(instr, -1, frame_state_offset, |
265 OutputFrameStateCombine::Ignore()); | 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->GetSize(); 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->IsDoubleStackSlot() || 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( | 299 struct OperandAndType { |
300 OperandAndType(InstructionOperand* operand, MachineType type) | |
301 : operand_(operand), type_(type) {} | |
302 | |
303 InstructionOperand* operand_; | |
304 MachineType type_; | |
305 }; | |
306 | |
307 static OperandAndType TypedOperandForFrameState( | |
300 FrameStateDescriptor* descriptor, Instruction* instr, | 308 FrameStateDescriptor* descriptor, Instruction* instr, |
301 size_t frame_state_offset, size_t index, OutputFrameStateCombine combine) { | 309 size_t frame_state_offset, size_t index, OutputFrameStateCombine combine) { |
302 DCHECK(index < descriptor->GetSize(combine)); | 310 DCHECK(index < descriptor->GetSize(combine)); |
303 switch (combine.kind()) { | 311 switch (combine.kind()) { |
304 case OutputFrameStateCombine::kPushOutput: { | 312 case OutputFrameStateCombine::kPushOutput: { |
305 DCHECK(combine.GetPushCount() <= instr->OutputCount()); | 313 DCHECK(combine.GetPushCount() <= instr->OutputCount()); |
306 size_t size_without_output = | 314 size_t size_without_output = |
307 descriptor->GetSize(OutputFrameStateCombine::Ignore()); | 315 descriptor->GetSize(OutputFrameStateCombine::Ignore()); |
308 // If the index is past the existing stack items, return the output. | 316 // If the index is past the existing stack items, return the output. |
309 if (index >= size_without_output) { | 317 if (index >= size_without_output) { |
310 return instr->OutputAt(index - size_without_output); | 318 return OperandAndType(instr->OutputAt(index - size_without_output), |
319 kMachAnyTagged); | |
311 } | 320 } |
312 break; | 321 break; |
313 } | 322 } |
314 case OutputFrameStateCombine::kPokeAt: | 323 case OutputFrameStateCombine::kPokeAt: |
315 size_t index_from_top = | 324 size_t index_from_top = |
316 descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); | 325 descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt(); |
317 if (index >= index_from_top && | 326 if (index >= index_from_top && |
318 index < index_from_top + instr->OutputCount()) { | 327 index < index_from_top + instr->OutputCount()) { |
319 return instr->OutputAt(index - index_from_top); | 328 return OperandAndType(instr->OutputAt(index - index_from_top), |
329 kMachAnyTagged); | |
320 } | 330 } |
321 break; | 331 break; |
322 } | 332 } |
323 return instr->InputAt(frame_state_offset + index); | 333 return OperandAndType(instr->InputAt(frame_state_offset + index), |
334 descriptor->GetType(index)); | |
324 } | 335 } |
325 | 336 |
326 | 337 |
327 void CodeGenerator::BuildTranslationForFrameStateDescriptor( | 338 void CodeGenerator::BuildTranslationForFrameStateDescriptor( |
328 FrameStateDescriptor* descriptor, Instruction* instr, | 339 FrameStateDescriptor* descriptor, Instruction* instr, |
329 Translation* translation, size_t frame_state_offset, | 340 Translation* translation, size_t frame_state_offset, |
330 OutputFrameStateCombine state_combine) { | 341 OutputFrameStateCombine state_combine) { |
331 // Outer-most state must be added to translation first. | 342 // Outer-most state must be added to translation first. |
332 if (descriptor->outer_state() != NULL) { | 343 if (descriptor->outer_state() != NULL) { |
333 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, | 344 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, |
(...skipping 15 matching lines...) Expand all Loading... | |
349 descriptor->parameters_count())); | 360 descriptor->parameters_count())); |
350 break; | 361 break; |
351 case ARGUMENTS_ADAPTOR: | 362 case ARGUMENTS_ADAPTOR: |
352 translation->BeginArgumentsAdaptorFrame( | 363 translation->BeginArgumentsAdaptorFrame( |
353 id, static_cast<unsigned int>(descriptor->parameters_count())); | 364 id, static_cast<unsigned int>(descriptor->parameters_count())); |
354 break; | 365 break; |
355 } | 366 } |
356 | 367 |
357 frame_state_offset += descriptor->outer_state()->GetTotalSize(); | 368 frame_state_offset += descriptor->outer_state()->GetTotalSize(); |
358 for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) { | 369 for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) { |
359 InstructionOperand* op = OperandForFrameState( | 370 OperandAndType op = TypedOperandForFrameState( |
360 descriptor, instr, frame_state_offset, i, state_combine); | 371 descriptor, instr, frame_state_offset, i, state_combine); |
361 AddTranslationForOperand(translation, instr, op); | 372 AddTranslationForOperand(translation, instr, op.operand_, op.type_); |
362 } | 373 } |
363 } | 374 } |
364 | 375 |
365 | 376 |
366 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, | 377 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, |
367 size_t frame_state_offset, | 378 size_t frame_state_offset, |
368 OutputFrameStateCombine state_combine) { | 379 OutputFrameStateCombine state_combine) { |
369 FrameStateDescriptor* descriptor = | 380 FrameStateDescriptor* descriptor = |
370 GetFrameStateDescriptor(instr, frame_state_offset); | 381 GetFrameStateDescriptor(instr, frame_state_offset); |
371 frame_state_offset++; | 382 frame_state_offset++; |
372 | 383 |
373 Translation translation( | 384 Translation translation( |
374 &translations_, static_cast<int>(descriptor->GetFrameCount()), | 385 &translations_, static_cast<int>(descriptor->GetFrameCount()), |
375 static_cast<int>(descriptor->GetJSFrameCount()), zone()); | 386 static_cast<int>(descriptor->GetJSFrameCount()), zone()); |
376 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, | 387 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, |
377 frame_state_offset, state_combine); | 388 frame_state_offset, state_combine); |
378 | 389 |
379 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); | 390 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); |
380 | 391 |
381 deoptimization_states_.push_back(new (zone()) DeoptimizationState( | 392 deoptimization_states_.push_back(new (zone()) DeoptimizationState( |
382 descriptor->bailout_id(), translation.index(), pc_offset)); | 393 descriptor->bailout_id(), translation.index(), pc_offset)); |
383 | 394 |
384 return deoptimization_id; | 395 return deoptimization_id; |
385 } | 396 } |
386 | 397 |
387 | 398 |
388 void CodeGenerator::AddTranslationForOperand(Translation* translation, | 399 void CodeGenerator::AddTranslationForOperand(Translation* translation, |
389 Instruction* instr, | 400 Instruction* instr, |
390 InstructionOperand* op) { | 401 InstructionOperand* op, |
402 MachineType type) { | |
391 if (op->IsStackSlot()) { | 403 if (op->IsStackSlot()) { |
392 translation->StoreStackSlot(op->index()); | 404 if (type == kMachBool || type == kMachInt32 || type == kMachInt8 || |
405 type == kMachInt16) { | |
406 translation->StoreInt32StackSlot(op->index()); | |
407 } else if (type == kMachUint32) { | |
408 translation->StoreUint32StackSlot(op->index()); | |
409 } else if ((type & kRepMask) == kRepTagged) { | |
410 translation->StoreStackSlot(op->index()); | |
411 } else { | |
412 CHECK(false); | |
413 } | |
393 } else if (op->IsDoubleStackSlot()) { | 414 } else if (op->IsDoubleStackSlot()) { |
415 DCHECK_EQ(kRepFloat64, type & kRepMask); | |
titzer
2014/10/06 08:56:02
You probably need to account for float32 here as w
Jarin
2014/10/06 09:45:27
Done.
| |
394 translation->StoreDoubleStackSlot(op->index()); | 416 translation->StoreDoubleStackSlot(op->index()); |
395 } else if (op->IsRegister()) { | 417 } else if (op->IsRegister()) { |
396 InstructionOperandConverter converter(this, instr); | 418 InstructionOperandConverter converter(this, instr); |
397 translation->StoreRegister(converter.ToRegister(op)); | 419 if (type == kMachBool || type == kMachInt32 || type == kMachInt8 || |
420 type == kMachInt16) { | |
421 translation->StoreInt32Register(converter.ToRegister(op)); | |
422 } else if (type == kMachUint32) { | |
423 translation->StoreUint32Register(converter.ToRegister(op)); | |
424 } else if ((type & kRepMask) == kRepTagged) { | |
425 translation->StoreRegister(converter.ToRegister(op)); | |
426 } else { | |
427 CHECK(false); | |
428 } | |
398 } else if (op->IsDoubleRegister()) { | 429 } else if (op->IsDoubleRegister()) { |
430 DCHECK_EQ(kRepFloat64, type & kRepMask); | |
titzer
2014/10/06 08:56:01
And here.
Jarin
2014/10/06 09:45:27
Done.
| |
399 InstructionOperandConverter converter(this, instr); | 431 InstructionOperandConverter converter(this, instr); |
400 translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); | 432 translation->StoreDoubleRegister(converter.ToDoubleRegister(op)); |
401 } else if (op->IsImmediate()) { | 433 } else if (op->IsImmediate()) { |
402 InstructionOperandConverter converter(this, instr); | 434 InstructionOperandConverter converter(this, instr); |
403 Constant constant = converter.ToConstant(op); | 435 Constant constant = converter.ToConstant(op); |
404 Handle<Object> constant_object; | 436 Handle<Object> constant_object; |
405 switch (constant.type()) { | 437 switch (constant.type()) { |
406 case Constant::kInt32: | 438 case Constant::kInt32: |
439 DCHECK(type == kMachInt32 || type == kMachUint32); | |
407 constant_object = | 440 constant_object = |
408 isolate()->factory()->NewNumberFromInt(constant.ToInt32()); | 441 isolate()->factory()->NewNumberFromInt(constant.ToInt32()); |
409 break; | 442 break; |
410 case Constant::kFloat64: | 443 case Constant::kFloat64: |
444 DCHECK(type == kMachFloat64 || type == kMachAnyTagged); | |
411 constant_object = isolate()->factory()->NewNumber(constant.ToFloat64()); | 445 constant_object = isolate()->factory()->NewNumber(constant.ToFloat64()); |
412 break; | 446 break; |
413 case Constant::kHeapObject: | 447 case Constant::kHeapObject: |
448 DCHECK((type & kRepMask) == kRepTagged); | |
414 constant_object = constant.ToHeapObject(); | 449 constant_object = constant.ToHeapObject(); |
415 break; | 450 break; |
416 default: | 451 default: |
417 UNREACHABLE(); | 452 CHECK(false); |
418 } | 453 } |
419 int literal_id = DefineDeoptimizationLiteral(constant_object); | 454 int literal_id = DefineDeoptimizationLiteral(constant_object); |
420 translation->StoreLiteral(literal_id); | 455 translation->StoreLiteral(literal_id); |
421 } else { | 456 } else { |
422 UNREACHABLE(); | 457 CHECK(false); |
423 } | 458 } |
424 } | 459 } |
425 | 460 |
426 | 461 |
427 void CodeGenerator::MarkLazyDeoptSite() { | 462 void CodeGenerator::MarkLazyDeoptSite() { |
428 last_lazy_deopt_pc_ = masm()->pc_offset(); | 463 last_lazy_deopt_pc_ = masm()->pc_offset(); |
429 } | 464 } |
430 | 465 |
431 #if !V8_TURBOFAN_BACKEND | 466 #if !V8_TURBOFAN_BACKEND |
432 | 467 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 } | 505 } |
471 | 506 |
472 | 507 |
473 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } | 508 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } |
474 | 509 |
475 #endif // !V8_TURBOFAN_BACKEND | 510 #endif // !V8_TURBOFAN_BACKEND |
476 | 511 |
477 } // namespace compiler | 512 } // namespace compiler |
478 } // namespace internal | 513 } // namespace internal |
479 } // namespace v8 | 514 } // namespace v8 |
OLD | NEW |