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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 | 239 |
240 if (flags & CallDescriptor::kNeedsNopAfterCall) { | 240 if (flags & CallDescriptor::kNeedsNopAfterCall) { |
241 AddNopForSmiCodeInlining(); | 241 AddNopForSmiCodeInlining(); |
242 } | 242 } |
243 | 243 |
244 if (needs_frame_state) { | 244 if (needs_frame_state) { |
245 // If the frame state is present, it starts at argument 1 | 245 // If the frame state is present, it starts at argument 1 |
246 // (just after the code address). | 246 // (just after the code address). |
247 InstructionOperandConverter converter(this, instr); | 247 InstructionOperandConverter converter(this, instr); |
248 // Deoptimization info starts at argument 1 | 248 // Deoptimization info starts at argument 1 |
249 size_t frame_state_offset = 1; | 249 int frame_state_offset = 1; |
250 FrameStateDescriptor* descriptor = | 250 FrameStateDescriptor* descriptor = |
251 GetFrameStateDescriptor(instr, frame_state_offset); | 251 GetFrameStateDescriptor(instr, frame_state_offset); |
252 int pc_offset = masm()->pc_offset(); | 252 int pc_offset = masm()->pc_offset(); |
253 int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, | 253 int deopt_state_id = BuildTranslation(instr, pc_offset, frame_state_offset, |
254 descriptor->state_combine()); | 254 descriptor->state_combine()); |
255 // If the pre-call frame state differs from the post-call one, produce the | 255 // If the pre-call frame state differs from the post-call one, produce the |
256 // pre-call frame state, too. | 256 // pre-call frame state, too. |
257 // TODO(jarin) We might want to avoid building the pre-call frame state | 257 // TODO(jarin) We might want to avoid building the pre-call frame state |
258 // because it is only used to get locals and arguments (by the debugger and | 258 // because it is only used to get locals and arguments (by the debugger and |
259 // f.arguments), and those are the same in the pre-call and post-call | 259 // f.arguments), and those are the same in the pre-call and post-call |
260 // states. | 260 // states. |
261 if (descriptor->state_combine() != kIgnoreOutput) { | 261 if (descriptor->state_combine() != kIgnoreOutput) { |
262 deopt_state_id = | 262 deopt_state_id = |
263 BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput); | 263 BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput); |
264 } | 264 } |
265 #if DEBUG | 265 #if DEBUG |
266 // Make sure all the values live in stack slots or they are immediates. | 266 // 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 | 267 // (The values should not live in register because registers are clobbered |
268 // by calls.) | 268 // by calls.) |
269 for (size_t i = 0; i < descriptor->size(); i++) { | 269 for (int i = 0; i < descriptor->size(); i++) { |
270 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); | 270 InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i); |
271 CHECK(op->IsStackSlot() || op->IsImmediate()); | 271 CHECK(op->IsStackSlot() || op->IsImmediate()); |
272 } | 272 } |
273 #endif | 273 #endif |
274 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); | 274 safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id); |
275 } | 275 } |
276 } | 276 } |
277 | 277 |
278 | 278 |
279 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { | 279 int CodeGenerator::DefineDeoptimizationLiteral(Handle<Object> literal) { |
280 int result = static_cast<int>(deoptimization_literals_.size()); | 280 int result = static_cast<int>(deoptimization_literals_.size()); |
281 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { | 281 for (unsigned i = 0; i < deoptimization_literals_.size(); ++i) { |
282 if (deoptimization_literals_[i].is_identical_to(literal)) return i; | 282 if (deoptimization_literals_[i].is_identical_to(literal)) return i; |
283 } | 283 } |
284 deoptimization_literals_.push_back(literal); | 284 deoptimization_literals_.push_back(literal); |
285 return result; | 285 return result; |
286 } | 286 } |
287 | 287 |
288 | 288 |
289 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( | 289 FrameStateDescriptor* CodeGenerator::GetFrameStateDescriptor( |
290 Instruction* instr, size_t frame_state_offset) { | 290 Instruction* instr, int frame_state_offset) { |
291 InstructionOperandConverter i(this, instr); | 291 InstructionOperandConverter i(this, instr); |
292 InstructionSequence::StateId state_id = InstructionSequence::StateId::FromInt( | 292 InstructionSequence::StateId state_id = |
293 i.InputInt32(static_cast<int>(frame_state_offset))); | 293 InstructionSequence::StateId::FromInt(i.InputInt32(frame_state_offset)); |
294 return code()->GetFrameStateDescriptor(state_id); | 294 return code()->GetFrameStateDescriptor(state_id); |
295 } | 295 } |
296 | 296 |
297 | 297 |
298 void CodeGenerator::BuildTranslationForFrameStateDescriptor( | 298 void CodeGenerator::BuildTranslationForFrameStateDescriptor( |
299 FrameStateDescriptor* descriptor, Instruction* instr, | 299 FrameStateDescriptor* descriptor, Instruction* instr, |
300 Translation* translation, size_t frame_state_offset, | 300 Translation* translation, int frame_state_offset, |
301 OutputFrameStateCombine state_combine) { | 301 OutputFrameStateCombine state_combine) { |
302 // Outer-most state must be added to translation first. | 302 // Outer-most state must be added to translation first. |
303 if (descriptor->outer_state() != NULL) { | 303 if (descriptor->outer_state() != NULL) { |
304 BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr, | 304 BuildTranslationForFrameStateDescriptor( |
305 translation, frame_state_offset, | 305 descriptor->outer_state(), instr, translation, |
306 kIgnoreOutput); | 306 frame_state_offset + descriptor->size(), kIgnoreOutput); |
307 } | 307 } |
308 | 308 |
309 int id = Translation::kSelfLiteralId; | 309 int height = descriptor->size() - descriptor->parameters_count(); |
310 if (!descriptor->jsfunction().is_null()) { | 310 switch (state_combine) { |
311 id = DefineDeoptimizationLiteral( | 311 case kPushOutput: |
312 Handle<Object>::cast(descriptor->jsfunction().ToHandleChecked())); | 312 height++; |
313 } | |
314 | |
315 switch (descriptor->type()) { | |
316 case JS_FRAME: | |
317 translation->BeginJSFrame( | |
318 descriptor->bailout_id(), id, | |
319 static_cast<unsigned int>(descriptor->GetHeight(state_combine))); | |
320 break; | 313 break; |
321 case ARGUMENTS_ADAPTOR: | 314 case kIgnoreOutput: |
322 translation->BeginArgumentsAdaptorFrame( | |
323 id, static_cast<unsigned int>(descriptor->parameters_count())); | |
324 break; | 315 break; |
325 } | 316 } |
326 | 317 |
327 frame_state_offset += descriptor->outer_state()->GetTotalSize(); | 318 translation->BeginJSFrame(descriptor->bailout_id(), |
328 for (size_t i = 0; i < descriptor->size(); i++) { | 319 Translation::kSelfLiteralId, height); |
329 AddTranslationForOperand( | 320 |
330 translation, instr, | 321 for (int i = 0; i < descriptor->size(); i++) { |
331 instr->InputAt(static_cast<int>(frame_state_offset + i))); | 322 AddTranslationForOperand(translation, instr, |
| 323 instr->InputAt(i + frame_state_offset)); |
332 } | 324 } |
333 | 325 |
334 switch (state_combine) { | 326 switch (state_combine) { |
335 case kPushOutput: | 327 case kPushOutput: |
336 DCHECK(instr->OutputCount() == 1); | 328 DCHECK(instr->OutputCount() == 1); |
337 AddTranslationForOperand(translation, instr, instr->OutputAt(0)); | 329 AddTranslationForOperand(translation, instr, instr->OutputAt(0)); |
338 break; | 330 break; |
339 case kIgnoreOutput: | 331 case kIgnoreOutput: |
340 break; | 332 break; |
341 } | 333 } |
342 } | 334 } |
343 | 335 |
344 | 336 |
345 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, | 337 int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, |
346 size_t frame_state_offset, | 338 int frame_state_offset, |
347 OutputFrameStateCombine state_combine) { | 339 OutputFrameStateCombine state_combine) { |
348 FrameStateDescriptor* descriptor = | 340 FrameStateDescriptor* descriptor = |
349 GetFrameStateDescriptor(instr, frame_state_offset); | 341 GetFrameStateDescriptor(instr, frame_state_offset); |
350 frame_state_offset++; | 342 frame_state_offset++; |
351 | 343 |
352 Translation translation( | 344 int frame_count = descriptor->GetFrameCount(); |
353 &translations_, static_cast<int>(descriptor->GetFrameCount()), | 345 Translation translation(&translations_, frame_count, frame_count, zone()); |
354 static_cast<int>(descriptor->GetJSFrameCount()), zone()); | |
355 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, | 346 BuildTranslationForFrameStateDescriptor(descriptor, instr, &translation, |
356 frame_state_offset, state_combine); | 347 frame_state_offset, state_combine); |
357 | 348 |
358 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); | 349 int deoptimization_id = static_cast<int>(deoptimization_states_.size()); |
359 | 350 |
360 deoptimization_states_.push_back(new (zone()) DeoptimizationState( | 351 deoptimization_states_.push_back(new (zone()) DeoptimizationState( |
361 descriptor->bailout_id(), translation.index(), pc_offset)); | 352 descriptor->bailout_id(), translation.index(), pc_offset)); |
362 | 353 |
363 return deoptimization_id; | 354 return deoptimization_id; |
364 } | 355 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 } | 436 } |
446 | 437 |
447 | 438 |
448 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } | 439 void CodeGenerator::AddNopForSmiCodeInlining() { UNIMPLEMENTED(); } |
449 | 440 |
450 #endif // !V8_TURBOFAN_BACKEND | 441 #endif // !V8_TURBOFAN_BACKEND |
451 | 442 |
452 } // namespace compiler | 443 } // namespace compiler |
453 } // namespace internal | 444 } // namespace internal |
454 } // namespace v8 | 445 } // namespace v8 |
OLD | NEW |