OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved.7 | 1 // Copyright 2012 the V8 project authors. All rights reserved.7 |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 } | 317 } |
318 // Deferred code is the last part of the instruction sequence. Mark | 318 // Deferred code is the last part of the instruction sequence. Mark |
319 // the generated code as done unless we bailed out. | 319 // the generated code as done unless we bailed out. |
320 if (!is_aborted()) status_ = DONE; | 320 if (!is_aborted()) status_ = DONE; |
321 return !is_aborted(); | 321 return !is_aborted(); |
322 } | 322 } |
323 | 323 |
324 | 324 |
325 bool LCodeGen::GenerateDeoptJumpTable() { | 325 bool LCodeGen::GenerateDeoptJumpTable() { |
326 if (deopt_jump_table_.length() > 0) { | 326 if (deopt_jump_table_.length() > 0) { |
| 327 Label needs_frame, call_deopt_entry; |
| 328 |
327 Comment(";;; -------------------- Jump table --------------------"); | 329 Comment(";;; -------------------- Jump table --------------------"); |
328 } | 330 Address base = deopt_jump_table_[0].address; |
329 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 331 |
330 Label table_start; | 332 Register entry_offset = t9; |
331 __ bind(&table_start); | 333 |
332 Label needs_frame; | 334 int length = deopt_jump_table_.length(); |
333 for (int i = 0; i < deopt_jump_table_.length(); i++) { | 335 for (int i = 0; i < length; i++) { |
334 __ bind(&deopt_jump_table_[i].label); | 336 __ bind(&deopt_jump_table_[i].label); |
335 Address entry = deopt_jump_table_[i].address; | 337 |
336 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; | 338 Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; |
337 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); | 339 ASSERT(type == deopt_jump_table_[0].bailout_type); |
338 if (id == Deoptimizer::kNotDeoptimizationEntry) { | 340 Address entry = deopt_jump_table_[i].address; |
339 Comment(";;; jump table entry %d.", i); | 341 int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); |
340 } else { | 342 ASSERT(id != Deoptimizer::kNotDeoptimizationEntry); |
341 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); | 343 Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); |
| 344 |
| 345 // Second-level deopt table entries are contiguous and small, so instead |
| 346 // of loading the full, absolute address of each one, load an immediate |
| 347 // offset which will be added to the base address later. |
| 348 __ li(entry_offset, Operand(entry - base)); |
| 349 |
| 350 if (deopt_jump_table_[i].needs_frame) { |
| 351 ASSERT(!info()->saves_caller_doubles()); |
| 352 if (needs_frame.is_bound()) { |
| 353 __ Branch(&needs_frame); |
| 354 } else { |
| 355 __ bind(&needs_frame); |
| 356 Comment(";;; call deopt with frame"); |
| 357 __ MultiPush(cp.bit() | fp.bit() | ra.bit()); |
| 358 // This variant of deopt can only be used with stubs. Since we don't |
| 359 // have a function pointer to install in the stack frame that we're |
| 360 // building, install a special marker there instead. |
| 361 ASSERT(info()->IsStub()); |
| 362 __ li(at, Operand(Smi::FromInt(StackFrame::STUB))); |
| 363 __ push(at); |
| 364 __ Addu(fp, sp, |
| 365 Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 366 __ bind(&call_deopt_entry); |
| 367 // Add the base address to the offset previously loaded in |
| 368 // entry_offset. |
| 369 __ Addu(entry_offset, entry_offset, |
| 370 Operand(ExternalReference::ForDeoptEntry(base))); |
| 371 __ Call(entry_offset); |
| 372 } |
| 373 } else { |
| 374 // The last entry can fall through into `call_deopt_entry`, avoiding a |
| 375 // branch. |
| 376 bool need_branch = ((i + 1) != length) || call_deopt_entry.is_bound(); |
| 377 |
| 378 if (need_branch) __ Branch(&call_deopt_entry); |
| 379 } |
342 } | 380 } |
343 __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry))); | 381 |
344 if (deopt_jump_table_[i].needs_frame) { | 382 if (!call_deopt_entry.is_bound()) { |
345 ASSERT(!info()->saves_caller_doubles()); | 383 Comment(";;; call deopt"); |
346 if (needs_frame.is_bound()) { | 384 __ bind(&call_deopt_entry); |
347 __ Branch(&needs_frame); | 385 |
348 } else { | |
349 __ bind(&needs_frame); | |
350 __ MultiPush(cp.bit() | fp.bit() | ra.bit()); | |
351 // This variant of deopt can only be used with stubs. Since we don't | |
352 // have a function pointer to install in the stack frame that we're | |
353 // building, install a special marker there instead. | |
354 ASSERT(info()->IsStub()); | |
355 __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); | |
356 __ push(scratch0()); | |
357 __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
358 __ Call(t9); | |
359 } | |
360 } else { | |
361 if (info()->saves_caller_doubles()) { | 386 if (info()->saves_caller_doubles()) { |
362 ASSERT(info()->IsStub()); | 387 ASSERT(info()->IsStub()); |
363 RestoreCallerDoubles(); | 388 RestoreCallerDoubles(); |
364 } | 389 } |
365 __ Call(t9); | 390 |
| 391 // Add the base address to the offset previously loaded in entry_offset. |
| 392 __ Addu(entry_offset, entry_offset, |
| 393 Operand(ExternalReference::ForDeoptEntry(base))); |
| 394 __ Call(entry_offset); |
366 } | 395 } |
367 } | 396 } |
368 __ RecordComment("]"); | 397 __ RecordComment("]"); |
369 | 398 |
370 // The deoptimization jump table is the last part of the instruction | 399 // The deoptimization jump table is the last part of the instruction |
371 // sequence. Mark the generated code as done unless we bailed out. | 400 // sequence. Mark the generated code as done unless we bailed out. |
372 if (!is_aborted()) status_ = DONE; | 401 if (!is_aborted()) status_ = DONE; |
373 return !is_aborted(); | 402 return !is_aborted(); |
374 } | 403 } |
375 | 404 |
(...skipping 5508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5884 __ li(at, scope_info); | 5913 __ li(at, scope_info); |
5885 __ Push(at, ToRegister(instr->function())); | 5914 __ Push(at, ToRegister(instr->function())); |
5886 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5915 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5887 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5916 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5888 } | 5917 } |
5889 | 5918 |
5890 | 5919 |
5891 #undef __ | 5920 #undef __ |
5892 | 5921 |
5893 } } // namespace v8::internal | 5922 } } // namespace v8::internal |
OLD | NEW |