| 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 |