 Chromium Code Reviews
 Chromium Code Reviews Issue 614713002:
  Relax representation requirement in FrameStates.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 614713002:
  Relax representation requirement in FrameStates.  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| 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 |