Revision f230a1cf deps/v8/src/x64/deoptimizer-x64.cc
deps/v8/src/x64/deoptimizer-x64.cc | ||
---|---|---|
82 | 82 |
} |
83 | 83 |
|
84 | 84 |
|
85 |
static const byte kJnsInstruction = 0x79; |
|
86 |
static const byte kJnsOffset = 0x1d; |
|
87 |
static const byte kCallInstruction = 0xe8; |
|
88 |
static const byte kNopByteOne = 0x66; |
|
89 |
static const byte kNopByteTwo = 0x90; |
|
90 |
|
|
91 |
// The back edge bookkeeping code matches the pattern: |
|
92 |
// |
|
93 |
// add <profiling_counter>, <-delta> |
|
94 |
// jns ok |
|
95 |
// call <stack guard> |
|
96 |
// ok: |
|
97 |
// |
|
98 |
// We will patch away the branch so the code is: |
|
99 |
// |
|
100 |
// add <profiling_counter>, <-delta> ;; Not changed |
|
101 |
// nop |
|
102 |
// nop |
|
103 |
// call <on-stack replacment> |
|
104 |
// ok: |
|
105 |
|
|
106 |
void Deoptimizer::PatchInterruptCodeAt(Code* unoptimized_code, |
|
107 |
Address pc_after, |
|
108 |
Code* replacement_code) { |
|
109 |
// Turn the jump into nops. |
|
110 |
Address call_target_address = pc_after - kIntSize; |
|
111 |
*(call_target_address - 3) = kNopByteOne; |
|
112 |
*(call_target_address - 2) = kNopByteTwo; |
|
113 |
// Replace the call address. |
|
114 |
Assembler::set_target_address_at(call_target_address, |
|
115 |
replacement_code->entry()); |
|
116 |
|
|
117 |
unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
|
118 |
unoptimized_code, call_target_address, replacement_code); |
|
119 |
} |
|
120 |
|
|
121 |
|
|
122 |
void Deoptimizer::RevertInterruptCodeAt(Code* unoptimized_code, |
|
123 |
Address pc_after, |
|
124 |
Code* interrupt_code) { |
|
125 |
// Restore the original jump. |
|
126 |
Address call_target_address = pc_after - kIntSize; |
|
127 |
*(call_target_address - 3) = kJnsInstruction; |
|
128 |
*(call_target_address - 2) = kJnsOffset; |
|
129 |
// Restore the original call address. |
|
130 |
Assembler::set_target_address_at(call_target_address, |
|
131 |
interrupt_code->entry()); |
|
132 |
|
|
133 |
interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
|
134 |
unoptimized_code, call_target_address, interrupt_code); |
|
135 |
} |
|
136 |
|
|
137 |
|
|
138 |
#ifdef DEBUG |
|
139 |
Deoptimizer::InterruptPatchState Deoptimizer::GetInterruptPatchState( |
|
140 |
Isolate* isolate, |
|
141 |
Code* unoptimized_code, |
|
142 |
Address pc_after) { |
|
143 |
Address call_target_address = pc_after - kIntSize; |
|
144 |
ASSERT_EQ(kCallInstruction, *(call_target_address - 1)); |
|
145 |
if (*(call_target_address - 3) == kNopByteOne) { |
|
146 |
ASSERT_EQ(kNopByteTwo, *(call_target_address - 2)); |
|
147 |
Code* osr_builtin = |
|
148 |
isolate->builtins()->builtin(Builtins::kOnStackReplacement); |
|
149 |
ASSERT_EQ(osr_builtin->entry(), |
|
150 |
Assembler::target_address_at(call_target_address)); |
|
151 |
return PATCHED_FOR_OSR; |
|
152 |
} else { |
|
153 |
// Get the interrupt stub code object to match against from cache. |
|
154 |
Code* interrupt_builtin = |
|
155 |
isolate->builtins()->builtin(Builtins::kInterruptCheck); |
|
156 |
ASSERT_EQ(interrupt_builtin->entry(), |
|
157 |
Assembler::target_address_at(call_target_address)); |
|
158 |
ASSERT_EQ(kJnsInstruction, *(call_target_address - 3)); |
|
159 |
ASSERT_EQ(kJnsOffset, *(call_target_address - 2)); |
|
160 |
return NOT_PATCHED; |
|
161 |
} |
|
162 |
} |
|
163 |
#endif // DEBUG |
|
164 |
|
|
165 |
|
|
166 | 85 |
void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) { |
167 | 86 |
// Set the register values. The values are not important as there are no |
168 | 87 |
// callee saved registers in JavaScript frames, so all registers are |
... | ... | |
187 | 106 |
FrameDescription* output_frame, CodeStubInterfaceDescriptor* descriptor) { |
188 | 107 |
intptr_t handler = |
189 | 108 |
reinterpret_cast<intptr_t>(descriptor->deoptimization_handler_); |
190 |
int params = descriptor->register_param_count_; |
|
191 |
if (descriptor->stack_parameter_count_ != NULL) { |
|
192 |
params++; |
|
193 |
} |
|
109 |
int params = descriptor->environment_length(); |
|
194 | 110 |
output_frame->SetRegister(rax.code(), params); |
195 | 111 |
output_frame->SetRegister(rbx.code(), handler); |
196 | 112 |
} |
Also available in: Unified diff