Index: src/deoptimizer.cc |
=================================================================== |
--- src/deoptimizer.cc (revision 9531) |
+++ src/deoptimizer.cc (working copy) |
@@ -52,11 +52,13 @@ |
DeoptimizerData::~DeoptimizerData() { |
if (eager_deoptimization_entry_code_ != NULL) { |
- eager_deoptimization_entry_code_->Free(EXECUTABLE); |
+ Isolate::Current()->memory_allocator()->Free( |
+ eager_deoptimization_entry_code_); |
eager_deoptimization_entry_code_ = NULL; |
} |
if (lazy_deoptimization_entry_code_ != NULL) { |
- lazy_deoptimization_entry_code_->Free(EXECUTABLE); |
+ Isolate::Current()->memory_allocator()->Free( |
+ lazy_deoptimization_entry_code_); |
lazy_deoptimization_entry_code_ = NULL; |
} |
} |
@@ -71,6 +73,8 @@ |
#endif |
+// We rely on this function not causing a GC. It is called from generated code |
+// without having a real stack frame in place. |
Deoptimizer* Deoptimizer::New(JSFunction* function, |
BailoutType type, |
unsigned bailout_id, |
@@ -319,6 +323,8 @@ |
input_(NULL), |
output_count_(0), |
output_(NULL), |
+ frame_alignment_marker_(isolate->heap()->frame_alignment_marker()), |
+ has_alignment_padding_(0), |
deferred_heap_numbers_(0) { |
if (FLAG_trace_deopt && type != OSR) { |
if (type == DEBUGGER) { |
@@ -343,6 +349,26 @@ |
if (type == EAGER) { |
ASSERT(from == NULL); |
optimized_code_ = function_->code(); |
+ if (FLAG_trace_deopt && FLAG_code_comments) { |
+ // Print instruction associated with this bailout. |
+ const char* last_comment = NULL; |
+ int mask = RelocInfo::ModeMask(RelocInfo::COMMENT) |
+ | RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); |
+ for (RelocIterator it(optimized_code_, mask); !it.done(); it.next()) { |
+ RelocInfo* info = it.rinfo(); |
+ if (info->rmode() == RelocInfo::COMMENT) { |
+ last_comment = reinterpret_cast<const char*>(info->data()); |
+ } |
+ if (info->rmode() == RelocInfo::RUNTIME_ENTRY) { |
+ unsigned id = Deoptimizer::GetDeoptimizationId( |
+ info->target_address(), Deoptimizer::EAGER); |
+ if (id == bailout_id && last_comment != NULL) { |
+ PrintF(" %s\n", last_comment); |
+ break; |
+ } |
+ } |
+ } |
+ } |
} else if (type == LAZY) { |
optimized_code_ = FindDeoptimizingCodeFromAddress(from); |
ASSERT(optimized_code_ != NULL); |
@@ -386,7 +412,7 @@ |
Address Deoptimizer::GetDeoptimizationEntry(int id, BailoutType type) { |
ASSERT(id >= 0); |
if (id >= kNumberOfEntries) return NULL; |
- LargeObjectChunk* base = NULL; |
+ MemoryChunk* base = NULL; |
DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
if (type == EAGER) { |
if (data->eager_deoptimization_entry_code_ == NULL) { |
@@ -400,12 +426,12 @@ |
base = data->lazy_deoptimization_entry_code_; |
} |
return |
- static_cast<Address>(base->GetStartAddress()) + (id * table_entry_size_); |
+ static_cast<Address>(base->body()) + (id * table_entry_size_); |
} |
int Deoptimizer::GetDeoptimizationId(Address addr, BailoutType type) { |
- LargeObjectChunk* base = NULL; |
+ MemoryChunk* base = NULL; |
DeoptimizerData* data = Isolate::Current()->deoptimizer_data(); |
if (type == EAGER) { |
base = data->eager_deoptimization_entry_code_; |
@@ -413,14 +439,14 @@ |
base = data->lazy_deoptimization_entry_code_; |
} |
if (base == NULL || |
- addr < base->GetStartAddress() || |
- addr >= base->GetStartAddress() + |
+ addr < base->body() || |
+ addr >= base->body() + |
(kNumberOfEntries * table_entry_size_)) { |
return kNotDeoptimizationEntry; |
} |
ASSERT_EQ(0, |
- static_cast<int>(addr - base->GetStartAddress()) % table_entry_size_); |
- return static_cast<int>(addr - base->GetStartAddress()) / table_entry_size_; |
+ static_cast<int>(addr - base->body()) % table_entry_size_); |
+ return static_cast<int>(addr - base->body()) / table_entry_size_; |
} |
@@ -462,6 +488,8 @@ |
} |
+// We rely on this function not causing a GC. It is called from generated code |
+// without having a real stack frame in place. |
void Deoptimizer::DoComputeOutputFrames() { |
if (bailout_type_ == OSR) { |
DoComputeOsrOutputFrame(); |
@@ -613,11 +641,13 @@ |
intptr_t input_value = input_->GetRegister(input_reg); |
if (FLAG_trace_deopt) { |
PrintF( |
- " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s\n", |
+ " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
output_[frame_index]->GetTop() + output_offset, |
output_offset, |
input_value, |
converter.NameOfCPURegister(input_reg)); |
+ reinterpret_cast<Object*>(input_value)->ShortPrint(); |
+ PrintF("\n"); |
} |
output_[frame_index]->SetFrameSlot(output_offset, input_value); |
return; |
@@ -675,10 +705,12 @@ |
if (FLAG_trace_deopt) { |
PrintF(" 0x%08" V8PRIxPTR ": ", |
output_[frame_index]->GetTop() + output_offset); |
- PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d]\n", |
+ PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d] ", |
output_offset, |
input_value, |
input_offset); |
+ reinterpret_cast<Object*>(input_value)->ShortPrint(); |
+ PrintF("\n"); |
} |
output_[frame_index]->SetFrameSlot(output_offset, input_value); |
return; |
@@ -953,7 +985,10 @@ |
for (uint32_t i = 0; i < table_length; ++i) { |
uint32_t pc_offset = Memory::uint32_at(stack_check_cursor + kIntSize); |
Address pc_after = unoptimized_code->instruction_start() + pc_offset; |
- PatchStackCheckCodeAt(pc_after, check_code, replacement_code); |
+ PatchStackCheckCodeAt(unoptimized_code, |
+ pc_after, |
+ check_code, |
+ replacement_code); |
stack_check_cursor += 2 * kIntSize; |
} |
} |
@@ -1039,7 +1074,7 @@ |
} |
-LargeObjectChunk* Deoptimizer::CreateCode(BailoutType type) { |
+MemoryChunk* Deoptimizer::CreateCode(BailoutType type) { |
// We cannot run this if the serializer is enabled because this will |
// cause us to emit relocation information for the external |
// references. This is fine because the deoptimizer's code section |
@@ -1053,12 +1088,15 @@ |
masm.GetCode(&desc); |
ASSERT(desc.reloc_size == 0); |
- LargeObjectChunk* chunk = LargeObjectChunk::New(desc.instr_size, EXECUTABLE); |
+ MemoryChunk* chunk = |
+ Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size, |
+ EXECUTABLE, |
+ NULL); |
if (chunk == NULL) { |
V8::FatalProcessOutOfMemory("Not enough memory for deoptimization table"); |
} |
- memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); |
- CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); |
+ memcpy(chunk->body(), desc.buffer, desc.instr_size); |
+ CPU::FlushICache(chunk->body(), desc.instr_size); |
return chunk; |
} |