Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: src/arm64/lithium-codegen-arm64.cc

Issue 305963010: ARM64: Restructure the L1 deopt jump table. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/lithium-codegen-arm64.cc
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index 1d4f6ebd16fd766d6461a4fba87b2c2e87dc52d2..6ca7e4d55830325f758509df8c790b1399aa1188 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -832,51 +832,82 @@ bool LCodeGen::GenerateDeferredCode() {
bool LCodeGen::GenerateDeoptJumpTable() {
+ Label needs_frame, restore_caller_doubles, call_deopt_entry;
+
if (deopt_jump_table_.length() > 0) {
Comment(";;; -------------------- Jump table --------------------");
- }
- Label table_start;
- __ bind(&table_start);
- Label needs_frame;
- for (int i = 0; i < deopt_jump_table_.length(); i++) {
- __ Bind(&deopt_jump_table_[i]->label);
- Address entry = deopt_jump_table_[i]->address;
- Deoptimizer::BailoutType type = deopt_jump_table_[i]->bailout_type;
- int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
- if (id == Deoptimizer::kNotDeoptimizationEntry) {
- Comment(";;; jump table entry %d.", i);
- } else {
- Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
- }
- if (deopt_jump_table_[i]->needs_frame) {
- ASSERT(!info()->saves_caller_doubles());
+ Address base = deopt_jump_table_[0]->address;
- UseScratchRegisterScope temps(masm());
- Register stub_deopt_entry = temps.AcquireX();
- Register stub_marker = temps.AcquireX();
+ UseScratchRegisterScope temps(masm());
+ Register entry_offset = temps.AcquireX();
+
+ int length = deopt_jump_table_.length();
+ for (int i = 0; i < length; i++) {
+ __ Bind(&deopt_jump_table_[i]->label);
- __ Mov(stub_deopt_entry, ExternalReference::ForDeoptEntry(entry));
- if (needs_frame.is_bound()) {
- __ B(&needs_frame);
+ Deoptimizer::BailoutType type = deopt_jump_table_[i]->bailout_type;
+ Address entry = deopt_jump_table_[i]->address;
+ int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type);
+ if (id == Deoptimizer::kNotDeoptimizationEntry) {
+ Comment(";;; jump table entry %d.", i);
} else {
- __ Bind(&needs_frame);
- // This variant of deopt can only be used with stubs. Since we don't
- // have a function pointer to install in the stack frame that we're
- // building, install a special marker there instead.
- ASSERT(info()->IsStub());
- __ Mov(stub_marker, Smi::FromInt(StackFrame::STUB));
- __ Push(lr, fp, cp, stub_marker);
- __ Add(fp, __ StackPointer(), 2 * kPointerSize);
- __ Call(stub_deopt_entry);
+ Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id);
}
- } else {
- if (info()->saves_caller_doubles()) {
+
+ // Second-level deopt table entries are contiguous and small, so instead
+ // of loading the full, absolute address of each one, load the base
+ // address and add an immediate offset.
+ __ Mov(entry_offset, entry - base);
+
+ // The last entry can fall through into `call_deopt_entry`, avoiding a
+ // branch.
+ bool last_entry = (i + 1) == length;
+
+ if (deopt_jump_table_[i]->needs_frame) {
+ ASSERT(!info()->saves_caller_doubles());
+ if (!needs_frame.is_bound()) {
+ // This variant of deopt can only be used with stubs. Since we don't
+ // have a function pointer to install in the stack frame that we're
+ // building, install a special marker there instead.
+ ASSERT(info()->IsStub());
+
+ UseScratchRegisterScope temps(masm());
+ Register stub_marker = temps.AcquireX();
+ __ Bind(&needs_frame);
+ __ Mov(stub_marker, Smi::FromInt(StackFrame::STUB));
+ __ Push(lr, fp, cp, stub_marker);
+ __ Add(fp, __ StackPointer(), 2 * kPointerSize);
+ if (!last_entry) __ B(&call_deopt_entry);
+ } else {
+ // Reuse the existing needs_frame code.
+ __ B(&needs_frame);
+ }
+ } else if (info()->saves_caller_doubles()) {
ASSERT(info()->IsStub());
- RestoreCallerDoubles();
+ if (!restore_caller_doubles.is_bound()) {
+ __ Bind(&restore_caller_doubles);
+ RestoreCallerDoubles();
+ if (!last_entry) __ B(&call_deopt_entry);
+ } else {
+ // Reuse the existing restore_caller_doubles code.
+ __ B(&restore_caller_doubles);
+ }
+ } else {
+ // There is nothing special to do, so just continue to the second-level
+ // table.
+ if (!last_entry) __ B(&call_deopt_entry);
}
- __ Call(entry, RelocInfo::RUNTIME_ENTRY);
+
+ masm()->CheckConstPool(false, last_entry);
}
- masm()->CheckConstPool(false, false);
+
+ // Generate common code for calling the second-level deopt table.
+ Register deopt_entry = temps.AcquireX();
+ __ Bind(&call_deopt_entry);
+ __ Mov(deopt_entry, Operand(reinterpret_cast<uint64_t>(base),
+ RelocInfo::RUNTIME_ENTRY));
+ __ Add(deopt_entry, deopt_entry, entry_offset);
+ __ Call(deopt_entry);
}
// Force constant pool emission at the end of the deopt jump table to make
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698