44
44
int Deoptimizer::patch_size() {
45
return MacroAssembler::kCallInstructionLength;
50
// Overwrites code with int3 instructions.
51
static void ZapCodeRange(Address from, Address to) {
53
int length = static_cast<int>(to - from);
54
CodePatcher destroyer(from, length);
55
while (length-- > 0) {
56
destroyer.masm()->int3();
62
// Iterate through the entries of a SafepointTable that corresponds to
63
// deoptimization points.
64
class SafepointTableDeoptimiztionEntryIterator {
66
explicit SafepointTableDeoptimiztionEntryIterator(Code* code)
67
: code_(code), table_(code), index_(-1), limit_(table_.length()) {
71
SafepointEntry Next(Address* pc) {
72
if (index_ >= limit_) {
74
return SafepointEntry(); // Invalid entry.
76
*pc = code_->instruction_start() + table_.GetPcOffset(index_);
77
SafepointEntry entry = table_.GetEntry(index_);
83
void FindNextIndex() {
84
ASSERT(index_ < limit_);
85
while (++index_ < limit_) {
86
if (table_.GetEntry(index_).deoptimization_index() !=
87
Safepoint::kNoDeoptimizationIndex) {
94
SafepointTable table_;
95
// Index of next deoptimization entry. If negative after calling
96
// FindNextIndex, there are no more, and Next will return an invalid
104
void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
105
// TODO(1276): Implement.
45
return Assembler::kCallInstructionLength;
119
59
// code patching below, and is not needed any more.
120
60
code->InvalidateRelocation();
122
// For each return after a safepoint insert a absolute call to the
62
// For each LLazyBailout instruction insert a absolute call to the
123
63
// corresponding deoptimization entry, or a short call to an absolute
124
64
// jump if space is short. The absolute jumps are put in a table just
125
65
// before the safepoint table (space was allocated there when the Code
126
66
// object was created, if necessary).
128
68
Address instruction_start = function->code()->instruction_start();
129
Address jump_table_address =
130
instruction_start + function->code()->safepoint_table_offset();
132
Address previous_pc = instruction_start;
135
SafepointTableDeoptimiztionEntryIterator deoptimizations(function->code());
136
Address entry_pc = NULL;
138
SafepointEntry current_entry = deoptimizations.Next(&entry_pc);
139
while (current_entry.is_valid()) {
140
int gap_code_size = current_entry.gap_code_size();
141
unsigned deoptimization_index = current_entry.deoptimization_index();
144
// Destroy the code which is not supposed to run again.
145
ZapCodeRange(previous_pc, entry_pc);
70
Address prev_call_address = NULL;
72
DeoptimizationInputData* deopt_data =
73
DeoptimizationInputData::cast(code->deoptimization_data());
74
for (int i = 0; i < deopt_data->DeoptCount(); i++) {
75
if (deopt_data->Pc(i)->value() == -1) continue;
147
76
// Position where Call will be patched in.
148
Address call_address = entry_pc + gap_code_size;
149
// End of call instruction, if using a direct call to a 64-bit address.
150
Address call_end_address =
151
call_address + MacroAssembler::kCallInstructionLength;
153
// Find next deoptimization entry, if any.
154
Address next_pc = NULL;
155
SafepointEntry next_entry = deoptimizations.Next(&next_pc);
157
if (!next_entry.is_valid() || next_pc >= call_end_address) {
158
// Room enough to write a long call instruction.
159
CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
160
patcher.masm()->Call(GetDeoptimizationEntry(deoptimization_index, LAZY),
163
previous_pc = call_end_address;
166
// Not room enough for a long Call instruction. Write a short call
167
// instruction to a long jump placed elsewhere in the code.
169
Address short_call_end_address =
170
call_address + MacroAssembler::kShortCallInstructionLength;
172
ASSERT(next_pc >= short_call_end_address);
174
// Write jump in jump-table.
175
jump_table_address -= MacroAssembler::kJumpInstructionLength;
176
CodePatcher jump_patcher(jump_table_address,
177
MacroAssembler::kJumpInstructionLength);
178
jump_patcher.masm()->Jump(
179
GetDeoptimizationEntry(deoptimization_index, LAZY),
182
// Write call to jump at call_offset.
183
CodePatcher call_patcher(call_address,
184
MacroAssembler::kShortCallInstructionLength);
185
call_patcher.masm()->call(jump_table_address);
187
previous_pc = short_call_end_address;
191
// Continue with next deoptimization entry.
192
current_entry = next_entry;
77
Address call_address = instruction_start + deopt_data->Pc(i)->value();
78
// There is room enough to write a long call instruction because we pad
79
// LLazyBailout instructions with nops if necessary.
80
CodePatcher patcher(call_address, Assembler::kCallInstructionLength);
81
patcher.masm()->Call(GetDeoptimizationEntry(i, LAZY), RelocInfo::NONE);
82
ASSERT(prev_call_address == NULL ||
83
call_address >= prev_call_address + patch_size());
84
ASSERT(call_address + patch_size() <= code->instruction_end());
86
prev_call_address = call_address;
197
// Destroy the code which is not supposed to run again.
198
ZapCodeRange(previous_pc, jump_table_address);
90
Isolate* isolate = code->GetIsolate();
201
92
// Add the deoptimizing code to the list.
202
93
DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
203
DeoptimizerData* data = code->GetIsolate()->deoptimizer_data();
94
DeoptimizerData* data = isolate->deoptimizer_data();
204
95
node->set_next(data->deoptimizing_code_list_);
205
96
data->deoptimizing_code_list_ = node;
98
// We might be in the middle of incremental marking with compaction.
99
// Tell collector to treat this code object in a special way and
100
// ignore all slots that might have been recorded on it.
101
isolate->heap()->mark_compact_collector()->InvalidateCode(code);
207
103
// Set the code for the function to non-optimized version.
208
104
function->ReplaceCode(function->shared()->code());