Port count-based profiler to ARM

Review URL: https://chromiumcodereview.appspot.com/9837004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11120 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 75426432
......@@ -257,6 +257,7 @@ const Instr kBlxRegMask =
15 * B24 | 15 * B20 | 15 * B16 | 15 * B12 | 15 * B8 | 15 * B4;
const Instr kBlxRegPattern =
B24 | B21 | 15 * B16 | 15 * B12 | 15 * B8 | BLX;
const Instr kBlxIp = al | kBlxRegPattern | ip.code();
const Instr kMovMvnMask = 0x6d * B21 | 0xf * B16;
const Instr kMovMvnPattern = 0xd * B21;
const Instr kMovMvnFlip = B22;
......
......@@ -604,6 +604,7 @@ extern const Instr kLdrPCMask;
extern const Instr kLdrPCPattern;
extern const Instr kBlxRegMask;
extern const Instr kBlxRegPattern;
extern const Instr kBlxIp;
extern const Instr kMovMvnMask;
extern const Instr kMovMvnPattern;
......
......@@ -108,6 +108,10 @@ void Deoptimizer::DeoptimizeFunction(JSFunction* function) {
}
static const int32_t kBranchBeforeStackCheck = 0x2a000001;
static const int32_t kBranchBeforeInterrupt = 0x5a000004;
void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code,
Address pc_after,
Code* check_code,
......@@ -118,10 +122,16 @@ void Deoptimizer::PatchStackCheckCodeAt(Code* unoptimized_code,
// 2a 00 00 01 bcs ok
// e5 9f c? ?? ldr ip, [pc, <stack guard address>]
// e1 2f ff 3c blx ip
ASSERT(Memory::int32_at(pc_after - kInstrSize) ==
(al | B24 | B21 | 15*B16 | 15*B12 | 15*B8 | BLX | ip.code()));
ASSERT(Memory::int32_at(pc_after - kInstrSize) == kBlxIp);
ASSERT(Assembler::IsLdrPcImmediateOffset(
Assembler::instr_at(pc_after - 2 * kInstrSize)));
if (FLAG_count_based_interrupts) {
ASSERT_EQ(kBranchBeforeInterrupt,
Memory::int32_at(pc_after - 3 * kInstrSize));
} else {
ASSERT_EQ(kBranchBeforeStackCheck,
Memory::int32_at(pc_after - 3 * kInstrSize));
}
// We patch the code to the following form:
// e1 5d 00 0c cmp sp, <limit>
......@@ -155,13 +165,21 @@ void Deoptimizer::RevertStackCheckCodeAt(Code* unoptimized_code,
Code* check_code,
Code* replacement_code) {
const int kInstrSize = Assembler::kInstrSize;
ASSERT(Memory::uint32_at(pc_after - kInstrSize) == 0xe12fff3c);
ASSERT(Memory::uint8_at(pc_after - kInstrSize - 1) == 0xe5);
ASSERT(Memory::uint8_at(pc_after - kInstrSize - 2) == 0x9f);
ASSERT(Memory::int32_at(pc_after - kInstrSize) == kBlxIp);
ASSERT(Assembler::IsLdrPcImmediateOffset(
Assembler::instr_at(pc_after - 2 * kInstrSize)));
// Replace NOP with conditional jump.
CodePatcher patcher(pc_after - 3 * kInstrSize, 1);
patcher.masm()->b(+4, cs);
if (FLAG_count_based_interrupts) {
patcher.masm()->b(+16, pl);
ASSERT_EQ(kBranchBeforeInterrupt,
Memory::int32_at(pc_after - 3 * kInstrSize));
} else {
patcher.masm()->b(+4, cs);
ASSERT_EQ(kBranchBeforeStackCheck,
Memory::int32_at(pc_after - 3 * kInstrSize));
}
// Replace the stack check address in the constant pool
// with the entry address of the replacement code.
......
This diff is collapsed.
......@@ -34,6 +34,7 @@
#include "compiler.h"
#include "debug.h"
#include "full-codegen.h"
#include "isolate-inl.h"
#include "parser.h"
#include "scopes.h"
#include "stub-cache.h"
......@@ -100,7 +101,9 @@ class JumpPatchSite BASE_EMBEDDED {
};
// TODO(jkummerow): Obsolete as soon as x64 is updated. Remove.
int FullCodeGenerator::self_optimization_header_size() {
UNREACHABLE();
return 13;
}
......@@ -321,12 +324,20 @@ void FullCodeGenerator::EmitProfilingCounterReset() {
// Self-optimization is a one-off thing: if it fails, don't try again.
reset_value = Smi::kMaxValue;
}
if (isolate()->IsDebuggerActive()) {
// Detect debug break requests as soon as possible.
reset_value = 10;
}
__ mov(ebx, Immediate(profiling_counter_));
__ mov(FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset),
Immediate(Smi::FromInt(reset_value)));
}
static const int kMaxBackEdgeWeight = 127;
static const int kBackEdgeDistanceDivisor = 100;
void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
Label* back_edge_target) {
Comment cmnt(masm_, "[ Stack check");
......@@ -337,7 +348,8 @@ void FullCodeGenerator::EmitStackCheck(IterationStatement* stmt,
if (FLAG_weighted_back_edges) {
ASSERT(back_edge_target->is_bound());
int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
weight = Min(127, Max(1, distance / 100));
weight = Min(kMaxBackEdgeWeight,
Max(1, distance / kBackEdgeDistanceDivisor));
}
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
......@@ -398,7 +410,8 @@ void FullCodeGenerator::EmitReturnSequence() {
weight = FLAG_interrupt_budget / FLAG_self_opt_count;
} else if (FLAG_weighted_back_edges) {
int distance = masm_->pc_offset();
weight = Min(127, Max(1, distance / 100));
weight = Min(kMaxBackEdgeWeight,
Max(1, distance / kBackEdgeDistanceDivisor));
}
EmitProfilingCounterDecrement(weight);
Label ok;
......
......@@ -49,6 +49,16 @@ SaveContext::SaveContext(Isolate* isolate) : prev_(isolate->save_context()) {
}
bool Isolate::IsDebuggerActive() {
#ifdef ENABLE_DEBUGGER_SUPPORT
if (!NoBarrier_Load(&debugger_initialized_)) return false;
return debugger()->IsDebuggerActive();
#else
return false;
#endif
}
bool Isolate::DebuggerHasBreakPoints() {
#ifdef ENABLE_DEBUGGER_SUPPORT
return debug()->has_break_points();
......
......@@ -929,6 +929,7 @@ class Isolate {
}
#endif
inline bool IsDebuggerActive();
inline bool DebuggerHasBreakPoints();
#ifdef DEBUG
......
......@@ -173,7 +173,7 @@ void RuntimeProfiler::AttemptOnStackReplacement(JSFunction* function) {
// prepared to generate it, but we don't expect to have to.
bool found_code = false;
Code* stack_check_code = NULL;
#ifdef V8_TARGET_ARCH_IA32
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
if (FLAG_count_based_interrupts) {
InterruptStub interrupt_stub;
found_code = interrupt_stub.FindCodeInCache(&stack_check_code);
......@@ -349,7 +349,7 @@ void RuntimeProfiler::OptimizeNow() {
void RuntimeProfiler::NotifyTick() {
#ifdef V8_TARGET_ARCH_IA32
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
if (FLAG_count_based_interrupts) return;
#endif
isolate_->stack_guard()->RequestRuntimeProfilerTick();
......
......@@ -8366,7 +8366,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
PrintF("]\n");
}
Handle<Code> check_code;
#ifdef V8_TARGET_ARCH_IA32
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_ARM)
if (FLAG_count_based_interrupts) {
InterruptStub interrupt_stub;
check_code = interrupt_stub.GetCode();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment