summaryrefslogtreecommitdiff
path: root/deps/v8/src/arm/deoptimizer-arm.cc
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
committerRyan Dahl <ry@tinyclouds.org>2011-06-29 17:26:51 +0200
commit33af2720f26c2b25bc7f75ce7eb454ff99db6d35 (patch)
tree9a38f0c96420edf503eebd6325dd8d2d8249f653 /deps/v8/src/arm/deoptimizer-arm.cc
parent6afdca885adeeeed9eef8cbb01c3d97af0bc084d (diff)
downloadnode-new-33af2720f26c2b25bc7f75ce7eb454ff99db6d35.tar.gz
Upgrade V8 to 3.4.8
Diffstat (limited to 'deps/v8/src/arm/deoptimizer-arm.cc')
-rw-r--r--deps/v8/src/arm/deoptimizer-arm.cc80
1 files changed, 60 insertions, 20 deletions
diff --git a/deps/v8/src/arm/deoptimizer-arm.cc b/deps/v8/src/arm/deoptimizer-arm.cc
index 339841875a..e0e84ab337 100644
--- a/deps/v8/src/arm/deoptimizer-arm.cc
+++ b/deps/v8/src/arm/deoptimizer-arm.cc
@@ -51,6 +51,7 @@ void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
+ HandleScope scope;
AssertNoAllocation no_allocation;
if (!function->IsOptimized()) return;
@@ -74,8 +75,6 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
int deoptimization_index = safepoint_entry.deoptimization_index();
int gap_code_size = safepoint_entry.gap_code_size();
// Check that we did not shoot past next safepoint.
- // TODO(srdjan): How do we guarantee that safepoint code does not
- // overlap other safepoint patching code?
CHECK(pc_offset >= last_pc_offset);
#ifdef DEBUG
// Destroy the code which is not supposed to be run again.
@@ -112,8 +111,9 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
// Add the deoptimizing code to the list.
DeoptimizingCodeListNode* node = new DeoptimizingCodeListNode(code);
- node->set_next(deoptimizing_code_list_);
- deoptimizing_code_list_ = node;
+ DeoptimizerData* data = code->GetIsolate()->deoptimizer_data();
+ node->set_next(data->deoptimizing_code_list_);
+ data->deoptimizing_code_list_ = node;
// Set the code for the function to non-optimized version.
function->ReplaceCode(function->shared()->code());
@@ -122,6 +122,11 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
PrintF("[forced deoptimization: ");
function->PrintName();
PrintF(" / %x]\n", reinterpret_cast<uint32_t>(function));
+#ifdef DEBUG
+ if (FLAG_print_code) {
+ code->PrintLn();
+ }
+#endif
}
}
@@ -283,14 +288,33 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
// There are no translation commands for the caller's pc and fp, the
// context, and the function. Set them up explicitly.
- for (int i = 0; ok && i < 4; i++) {
+ for (int i = StandardFrameConstants::kCallerPCOffset;
+ ok && i >= StandardFrameConstants::kMarkerOffset;
+ i -= kPointerSize) {
uint32_t input_value = input_->GetFrameSlot(input_offset);
if (FLAG_trace_osr) {
- PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part)\n",
+ const char* name = "UNKNOWN";
+ switch (i) {
+ case StandardFrameConstants::kCallerPCOffset:
+ name = "caller's pc";
+ break;
+ case StandardFrameConstants::kCallerFPOffset:
+ name = "fp";
+ break;
+ case StandardFrameConstants::kContextOffset:
+ name = "context";
+ break;
+ case StandardFrameConstants::kMarkerOffset:
+ name = "function";
+ break;
+ }
+ PrintF(" [sp + %d] <- 0x%08x ; [sp + %d] (fixed part - %s)\n",
output_offset,
input_value,
- input_offset);
+ input_offset,
+ name);
}
+
output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset));
input_offset -= kPointerSize;
output_offset -= kPointerSize;
@@ -316,7 +340,7 @@ void Deoptimizer::DoComputeOsrOutputFrame() {
optimized_code_->entry() + pc_offset);
output_[0]->SetPc(pc);
}
- Code* continuation = Builtins::builtin(Builtins::NotifyOSR);
+ Code* continuation = isolate_->builtins()->builtin(Builtins::kNotifyOSR);
output_[0]->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
@@ -490,11 +514,13 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
FullCodeGenerator::StateField::decode(pc_and_state);
output_frame->SetState(Smi::FromInt(state));
+
// Set the continuation for the topmost frame.
if (is_topmost) {
+ Builtins* builtins = isolate_->builtins();
Code* continuation = (bailout_type_ == EAGER)
- ? Builtins::builtin(Builtins::NotifyDeoptimized)
- : Builtins::builtin(Builtins::NotifyLazyDeoptimized);
+ ? builtins->builtin(Builtins::kNotifyDeoptimized)
+ : builtins->builtin(Builtins::kNotifyLazyDeoptimized);
output_frame->SetContinuation(
reinterpret_cast<uint32_t>(continuation->entry()));
}
@@ -510,6 +536,9 @@ void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
// easily ported.
void Deoptimizer::EntryGenerator::Generate() {
GeneratePrologue();
+
+ Isolate* isolate = masm()->isolate();
+
CpuFeatures::Scope scope(VFP3);
// Save all general purpose registers before messing with them.
const int kNumberOfRegisters = Register::kNumRegisters;
@@ -520,13 +549,21 @@ void Deoptimizer::EntryGenerator::Generate() {
const int kDoubleRegsSize =
kDoubleSize * DwVfpRegister::kNumAllocatableRegisters;
- // Save all general purpose registers before messing with them.
- __ sub(sp, sp, Operand(kDoubleRegsSize));
- for (int i = 0; i < DwVfpRegister::kNumAllocatableRegisters; ++i) {
- DwVfpRegister vfp_reg = DwVfpRegister::FromAllocationIndex(i);
- int offset = i * kDoubleSize;
- __ vstr(vfp_reg, sp, offset);
+ // Save all VFP registers before messing with them.
+ DwVfpRegister first = DwVfpRegister::FromAllocationIndex(0);
+ DwVfpRegister last =
+ DwVfpRegister::FromAllocationIndex(
+ DwVfpRegister::kNumAllocatableRegisters - 1);
+ ASSERT(last.code() > first.code());
+ ASSERT((last.code() - first.code()) ==
+ (DwVfpRegister::kNumAllocatableRegisters - 1));
+#ifdef DEBUG
+ for (int i = 0; i <= (DwVfpRegister::kNumAllocatableRegisters - 1); i++) {
+ ASSERT((DwVfpRegister::FromAllocationIndex(i).code() <= last.code()) &&
+ (DwVfpRegister::FromAllocationIndex(i).code() >= first.code()));
}
+#endif
+ __ vstm(db_w, sp, first, last);
// Push all 16 registers (needed to populate FrameDescription::registers_).
__ stm(db_w, sp, restored_regs | sp.bit() | lr.bit() | pc.bit());
@@ -557,14 +594,16 @@ void Deoptimizer::EntryGenerator::Generate() {
// Allocate a new deoptimizer object.
// Pass four arguments in r0 to r3 and fifth argument on stack.
- __ PrepareCallCFunction(5, r5);
+ __ PrepareCallCFunction(6, r5);
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
__ mov(r1, Operand(type())); // bailout type,
// r2: bailout id already loaded.
// r3: code address or 0 already loaded.
__ str(r4, MemOperand(sp, 0 * kPointerSize)); // Fp-to-sp delta.
+ __ mov(r5, Operand(ExternalReference::isolate_address()));
+ __ str(r5, MemOperand(sp, 1 * kPointerSize)); // Isolate.
// Call Deoptimizer::New().
- __ CallCFunction(ExternalReference::new_deoptimizer_function(), 5);
+ __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate), 6);
// Preserve "deoptimizer" object in register r0 and get the input
// frame descriptor pointer to r1 (deoptimizer->input_);
@@ -618,7 +657,8 @@ void Deoptimizer::EntryGenerator::Generate() {
// r0: deoptimizer object; r1: scratch.
__ PrepareCallCFunction(1, r1);
// Call Deoptimizer::ComputeOutputFrames().
- __ CallCFunction(ExternalReference::compute_output_frames_function(), 1);
+ __ CallCFunction(
+ ExternalReference::compute_output_frames_function(isolate), 1);
__ pop(r0); // Restore deoptimizer object (class Deoptimizer).
// Replace the current (input) frame with the output frames.
@@ -668,7 +708,7 @@ void Deoptimizer::EntryGenerator::Generate() {
__ pop(ip); // remove lr
// Set up the roots register.
- ExternalReference roots_address = ExternalReference::roots_address();
+ ExternalReference roots_address = ExternalReference::roots_address(isolate);
__ mov(r10, Operand(roots_address));
__ pop(ip); // remove pc