Revision: 10834
Author: [email protected]
Date: Sun Feb 26 23:49:14 2012
Log: Profiler experiments: Fix debugger in the presence of
self-optimization headers
Review URL: https://chromiumcodereview.appspot.com/9466012
http://code.google.com/p/v8/source/detail?r=10834
Modified:
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/full-codegen.cc
/branches/bleeding_edge/src/full-codegen.h
/branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
/branches/bleeding_edge/src/mips/full-codegen-mips.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/x64/full-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Feb 22 04:47:42
2012
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Sun Feb 26 23:49:14
2012
@@ -109,6 +109,11 @@
};
+int FullCodeGenerator::self_optimization_header_size() {
+ return 24;
+}
+
+
// Generate code for a JS function. On entry to the function the receiver
// and arguments have been pushed on the stack left to right. The actual
// argument count matches the formal parameter count expected by the
@@ -130,13 +135,6 @@
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
-#ifdef DEBUG
- if (strlen(FLAG_stop_at) > 0 &&
- info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
- __ stop("stop-at");
- }
-#endif
-
// We can optionally optimize based on counters rather than statistical
// sampling.
if (info->ShouldSelfOptimize()) {
@@ -144,6 +142,7 @@
PrintF("[adding self-optimization header to %s]\n",
*info->function()->debug_name()->ToCString());
}
+ has_self_optimization_header_ = true;
MaybeObject* maybe_cell =
isolate()->heap()->AllocateJSGlobalPropertyCell(
Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt));
JSGlobalPropertyCell* cell;
@@ -155,8 +154,16 @@
Handle<Code> compile_stub(
isolate()->builtins()->builtin(Builtins::kLazyRecompile));
__ Jump(compile_stub, RelocInfo::CODE_TARGET, eq);
+ ASSERT(masm_->pc_offset() == self_optimization_header_size());
}
}
+
+#ifdef DEBUG
+ if (strlen(FLAG_stop_at) > 0 &&
+ info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+ __ stop("stop-at");
+ }
+#endif
// Strict mode functions and builtins need to replace the receiver
// with undefined when called as functions (without an explicit
=======================================
--- /branches/bleeding_edge/src/debug.cc Fri Feb 3 06:16:40 2012
+++ /branches/bleeding_edge/src/debug.cc Sun Feb 26 23:49:14 2012
@@ -37,6 +37,7 @@
#include "debug.h"
#include "deoptimizer.h"
#include "execution.h"
+#include "full-codegen.h"
#include "global-handles.h"
#include "ic.h"
#include "ic-inl.h"
@@ -1752,7 +1753,6 @@
ASSERT(new_code->has_debug_break_slots());
ASSERT(current_code->is_compiled_optimizable() ==
new_code->is_compiled_optimizable());
- ASSERT(current_code->instruction_size() <=
new_code->instruction_size());
}
#endif
return result;
@@ -1830,6 +1830,13 @@
// break slots.
debug_break_slot_count++;
}
+ if (frame_code->has_self_optimization_header() &&
+ !new_code->has_self_optimization_header()) {
+ delta -= FullCodeGenerator::self_optimization_header_size();
+ } else {
+ ASSERT(frame_code->has_self_optimization_header() ==
+ new_code->has_self_optimization_header());
+ }
int debug_break_slot_bytes =
debug_break_slot_count * Assembler::kDebugBreakSlotLength;
if (FLAG_trace_deopt) {
=======================================
--- /branches/bleeding_edge/src/full-codegen.cc Mon Feb 20 04:57:23 2012
+++ /branches/bleeding_edge/src/full-codegen.cc Sun Feb 26 23:49:14 2012
@@ -302,6 +302,7 @@
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
code->set_optimizable(info->IsOptimizable());
+ code->set_self_optimization_header(cgen.has_self_optimization_header_);
cgen.PopulateDeoptimizationData(code);
cgen.PopulateTypeFeedbackInfo(code);
cgen.PopulateTypeFeedbackCells(code);
@@ -365,6 +366,7 @@
void FullCodeGenerator::PopulateTypeFeedbackInfo(Handle<Code> code) {
Handle<TypeFeedbackInfo> info =
isolate()->factory()->NewTypeFeedbackInfo();
info->set_ic_total_count(ic_total_count_);
+ ASSERT(!isolate()->heap()->InNewSpace(*info));
code->set_type_feedback_info(*info);
}
=======================================
--- /branches/bleeding_edge/src/full-codegen.h Wed Feb 22 04:47:42 2012
+++ /branches/bleeding_edge/src/full-codegen.h Sun Feb 26 23:49:14 2012
@@ -90,10 +90,15 @@
stack_checks_(2), // There's always at least one.
type_feedback_cells_(info->HasDeoptimizationSupport()
? info->function()->ast_node_count() : 0),
- ic_total_count_(0) { }
+ ic_total_count_(0),
+ has_self_optimization_header_(false) { }
static bool MakeCode(CompilationInfo* info);
+ // Returns the platform-specific size in bytes of the self-optimization
+ // header.
+ static int self_optimization_header_size();
+
// Encode state and pc-offset as a BitField<type, start, size>.
// Only use 30 bits because we encode the result as a smi.
class StateField : public BitField<State, 0, 1> { };
@@ -786,6 +791,7 @@
ZoneList<BailoutEntry> stack_checks_;
ZoneList<TypeFeedbackCellEntry> type_feedback_cells_;
int ic_total_count_;
+ bool has_self_optimization_header_;
Handle<FixedArray> handler_table_;
Handle<JSGlobalPropertyCell> profiling_counter_;
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Wed Feb 22
07:18:29 2012
+++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Sun Feb 26
23:49:14 2012
@@ -100,6 +100,11 @@
};
+int FullCodeGenerator::self_optimization_header_size() {
+ return 13;
+}
+
+
// Generate code for a JS function. On entry to the function the receiver
// and arguments have been pushed on the stack left to right, with the
// return address on top of them. The actual argument count matches the
@@ -122,13 +127,6 @@
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
-#ifdef DEBUG
- if (strlen(FLAG_stop_at) > 0 &&
- info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
- __ int3();
- }
-#endif
-
// We can optionally optimize based on counters rather than statistical
// sampling.
if (info->ShouldSelfOptimize()) {
@@ -136,6 +134,7 @@
PrintF("[adding self-optimization header to %s]\n",
*info->function()->debug_name()->ToCString());
}
+ has_self_optimization_header_ = true;
MaybeObject* maybe_cell =
isolate()->heap()->AllocateJSGlobalPropertyCell(
Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt));
JSGlobalPropertyCell* cell;
@@ -146,8 +145,16 @@
isolate()->builtins()->builtin(Builtins::kLazyRecompile));
STATIC_ASSERT(kSmiTag == 0);
__ j(zero, compile_stub);
+ ASSERT(masm_->pc_offset() == self_optimization_header_size());
}
}
+
+#ifdef DEBUG
+ if (strlen(FLAG_stop_at) > 0 &&
+ info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+ __ int3();
+ }
+#endif
// Strict mode functions and builtins need to replace the receiver
// with undefined when called as functions (without an explicit
=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Wed Feb 22
02:48:58 2012
+++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Sun Feb 26
23:49:14 2012
@@ -119,6 +119,11 @@
};
+int FullCodeGenerator::self_optimization_header_size() {
+ return 0; // TODO(jkummerow): determine correct value.
+}
+
+
// Generate code for a JS function. On entry to the function the receiver
// and arguments have been pushed on the stack left to right. The actual
// argument count matches the formal parameter count expected by the
@@ -140,13 +145,6 @@
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
-#ifdef DEBUG
- if (strlen(FLAG_stop_at) > 0 &&
- info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
- __ stop("stop-at");
- }
-#endif
-
// We can optionally optimize based on counters rather than statistical
// sampling.
if (info->ShouldSelfOptimize()) {
@@ -154,6 +152,7 @@
PrintF("[adding self-optimization header to %s]\n",
*info->function()->debug_name()->ToCString());
}
+ has_self_optimization_header_ = true;
MaybeObject* maybe_cell =
isolate()->heap()->AllocateJSGlobalPropertyCell(
Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt));
JSGlobalPropertyCell* cell;
@@ -165,8 +164,16 @@
Handle<Code> compile_stub(
isolate()->builtins()->builtin(Builtins::kLazyRecompile));
__ Jump(compile_stub, RelocInfo::CODE_TARGET, eq, a3,
Operand(zero_reg));
+ ASSERT(masm_->pc_offset() == self_optimization_header_size());
}
}
+
+#ifdef DEBUG
+ if (strlen(FLAG_stop_at) > 0 &&
+ info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+ __ stop("stop-at");
+ }
+#endif
// Strict mode functions and builtins need to replace the receiver
// with undefined when called as functions (without an explicit
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Fri Feb 24 06:34:01 2012
+++ /branches/bleeding_edge/src/objects-inl.h Sun Feb 26 23:49:14 2012
@@ -3087,6 +3087,21 @@
flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
}
+
+
+bool Code::has_self_optimization_header() {
+ ASSERT(kind() == FUNCTION);
+ byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
+ return FullCodeFlagsHasSelfOptimizationHeader::decode(flags);
+}
+
+
+void Code::set_self_optimization_header(bool value) {
+ ASSERT(kind() == FUNCTION);
+ byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
+ flags = FullCodeFlagsHasSelfOptimizationHeader::update(flags, value);
+ WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
+}
int Code::allow_osr_at_loop_nesting_level() {
=======================================
--- /branches/bleeding_edge/src/objects.h Fri Feb 24 06:34:01 2012
+++ /branches/bleeding_edge/src/objects.h Sun Feb 26 23:49:14 2012
@@ -4207,6 +4207,11 @@
inline bool is_compiled_optimizable();
inline void set_compiled_optimizable(bool value);
+ // [has_self_optimization_header]: For FUNCTION kind, tells if it has
+ // a self-optimization header.
+ inline bool has_self_optimization_header();
+ inline void set_self_optimization_header(bool value);
+
// [allow_osr_at_loop_nesting_level]: For FUNCTION kind, tells for
// how long the function has been marked for OSR and therefore which
// level of loop nesting we are willing to do on-stack replacement
@@ -4426,6 +4431,7 @@
public BitField<bool, 0, 1> {}; // NOLINT
class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1>
{};
class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
+ class FullCodeFlagsHasSelfOptimizationHeader: public BitField<bool, 3,
1> {};
static const int kBinaryOpReturnTypeOffset = kBinaryOpTypeOffset + 1;
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Wed Feb 22 04:47:42
2012
+++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Sun Feb 26 23:49:14
2012
@@ -100,6 +100,11 @@
};
+int FullCodeGenerator::self_optimization_header_size() {
+ return 20;
+}
+
+
// Generate code for a JS function. On entry to the function the receiver
// and arguments have been pushed on the stack left to right, with the
// return address on top of them. The actual argument count matches the
@@ -120,13 +125,6 @@
SetFunctionPosition(function());
Comment cmnt(masm_, "[ function compiled by full code generator");
-#ifdef DEBUG
- if (strlen(FLAG_stop_at) > 0 &&
- info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
- __ int3();
- }
-#endif
-
// We can optionally optimize based on counters rather than statistical
// sampling.
if (info->ShouldSelfOptimize()) {
@@ -134,6 +132,7 @@
PrintF("[adding self-optimization header to %s]\n",
*info->function()->debug_name()->ToCString());
}
+ has_self_optimization_header_ = true;
MaybeObject* maybe_cell =
isolate()->heap()->AllocateJSGlobalPropertyCell(
Smi::FromInt(Compiler::kCallsUntilPrimitiveOpt));
JSGlobalPropertyCell* cell;
@@ -145,8 +144,16 @@
Handle<Code> compile_stub(
isolate()->builtins()->builtin(Builtins::kLazyRecompile));
__ j(zero, compile_stub, RelocInfo::CODE_TARGET);
+ ASSERT(masm_->pc_offset() == self_optimization_header_size());
}
}
+
+#ifdef DEBUG
+ if (strlen(FLAG_stop_at) > 0 &&
+ info->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
+ __ int3();
+ }
+#endif
// Strict mode functions and builtins need to replace the receiver
// with undefined when called as functions (without an explicit
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev