"Use idle notification to reduce memory footprint.")
// ic.cc
DEFINE_BOOL(use_ic, true, "use inline caching")
+DEFINE_BOOL(trace_ic, false, "trace inline cache state transitions")
// macro-assembler-ia32.cc
DEFINE_BOOL(native_code_counters, false,
DEFINE_BOOL(print_handles, false, "report handles after GC")
DEFINE_BOOL(print_global_handles, false, "report global handles after GC")
-// ic.cc
-DEFINE_BOOL(trace_ic, false, "trace inline cache state transitions")
-
// interface.cc
DEFINE_BOOL(print_interfaces, false, "print interfaces")
DEFINE_BOOL(print_interface_details, false, "print interface inference details")
}
-void JavaScriptFrame::PrintTop(Isolate* isolate,
- FILE* file,
- bool print_args,
+void JavaScriptFrame::PrintFunctionAndOffset(JSFunction* function, Code* code,
+ Address pc, FILE* file,
+ bool print_line_number) {
+ PrintF(file, "%s", function->IsOptimized() ? "*" : "~");
+ function->PrintName(file);
+ int code_offset = static_cast<int>(pc - code->instruction_start());
+ PrintF(file, "+%d", code_offset);
+ if (print_line_number) {
+ SharedFunctionInfo* shared = function->shared();
+ int source_pos = code->SourcePosition(pc);
+ Object* maybe_script = shared->script();
+ if (maybe_script->IsScript()) {
+ Script* script = Script::cast(maybe_script);
+ int line = script->GetLineNumber(source_pos) + 1;
+ Object* script_name_raw = script->name();
+ if (script_name_raw->IsString()) {
+ String* script_name = String::cast(script->name());
+ SmartArrayPointer<char> c_script_name =
+ script_name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+ PrintF(file, " at %s:%d", c_script_name.get(), line);
+ } else {
+ PrintF(file, " at <unknown>:%d", line);
+ }
+ } else {
+ PrintF(file, " at <unknown>:<unknown>");
+ }
+ }
+}
+
+
+void JavaScriptFrame::PrintTop(Isolate* isolate, FILE* file, bool print_args,
bool print_line_number) {
// constructor calls
DisallowHeapAllocation no_allocation;
if (it.frame()->is_java_script()) {
JavaScriptFrame* frame = it.frame();
if (frame->IsConstructor()) PrintF(file, "new ");
- // function name
- JSFunction* fun = frame->function();
- fun->PrintName();
- Code* js_code = frame->unchecked_code();
- Address pc = frame->pc();
- int code_offset =
- static_cast<int>(pc - js_code->instruction_start());
- PrintF("+%d", code_offset);
- SharedFunctionInfo* shared = fun->shared();
- if (print_line_number) {
- Code* code = Code::cast(isolate->FindCodeObject(pc));
- int source_pos = code->SourcePosition(pc);
- Object* maybe_script = shared->script();
- if (maybe_script->IsScript()) {
- Script* script = Script::cast(maybe_script);
- int line = script->GetLineNumber(source_pos) + 1;
- Object* script_name_raw = script->name();
- if (script_name_raw->IsString()) {
- String* script_name = String::cast(script->name());
- SmartArrayPointer<char> c_script_name =
- script_name->ToCString(DISALLOW_NULLS,
- ROBUST_STRING_TRAVERSAL);
- PrintF(file, " at %s:%d", c_script_name.get(), line);
- } else {
- PrintF(file, " at <unknown>:%d", line);
- }
- } else {
- PrintF(file, " at <unknown>:<unknown>");
- }
- }
-
+ PrintFunctionAndOffset(frame->function(), frame->unchecked_code(),
+ frame->pc(), file, print_line_number);
if (print_args) {
// function arguments
// (we are intentionally only printing the actually
return static_cast<JavaScriptFrame*>(frame);
}
- static void PrintTop(Isolate* isolate,
- FILE* file,
- bool print_args,
+ static void PrintFunctionAndOffset(JSFunction* function, Code* code,
+ Address pc, FILE* file,
+ bool print_line_number);
+
+ static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
bool print_line_number);
protected:
namespace v8 {
namespace internal {
-#ifdef DEBUG
char IC::TransitionMarkFromState(IC::State state) {
switch (state) {
case UNINITIALIZED: return '0';
}
-void IC::TraceIC(const char* type,
- Handle<Object> name) {
+#ifdef DEBUG
+
+#define TRACE_GENERIC_IC(isolate, type, reason) \
+ do { \
+ if (FLAG_trace_ic) { \
+ PrintF("[%s patching generic stub in ", type); \
+ JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
+ PrintF(" (%s)]\n", reason); \
+ } \
+ } while (false)
+
+#else
+
+#define TRACE_GENERIC_IC(isolate, type, reason)
+
+#endif // DEBUG
+
+void IC::TraceIC(const char* type, Handle<Object> name) {
if (FLAG_trace_ic) {
Code* new_target = raw_target();
State new_state = new_target->ic_state();
PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type);
- StackFrameIterator it(isolate());
- while (it.frame()->fp() != this->fp()) it.Advance();
- StackFrame* raw_frame = it.frame();
- if (raw_frame->is_internal()) {
- Code* apply_builtin = isolate()->builtins()->builtin(
- Builtins::kFunctionApply);
- if (raw_frame->unchecked_code() == apply_builtin) {
- PrintF("apply from ");
- it.Advance();
- raw_frame = it.frame();
- }
+
+ // TODO(jkummerow): Add support for "apply". The logic is roughly:
+ // marker = [fp_ + kMarkerOffset];
+ // if marker is smi and marker.value == INTERNAL and
+ // the frame's code == builtin(Builtins::kFunctionApply):
+ // then print "apply from" and advance one frame
+
+ Object* maybe_function =
+ Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset);
+ if (maybe_function->IsJSFunction()) {
+ JSFunction* function = JSFunction::cast(maybe_function);
+ JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(),
+ stdout, true);
}
- JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
+
ExtraICState extra_state = new_target->extra_ic_state();
const char* modifier = "";
if (new_target->kind() == Code::KEYED_STORE_IC) {
}
}
-#define TRACE_GENERIC_IC(isolate, type, reason) \
- do { \
- if (FLAG_trace_ic) { \
- PrintF("[%s patching generic stub in ", type); \
- JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
- PrintF(" (%s)]\n", reason); \
- } \
- } while (false)
+#define TRACE_IC(type, name) TraceIC(type, name)
-#else
-#define TRACE_GENERIC_IC(isolate, type, reason)
-#endif // DEBUG
-
-#define TRACE_IC(type, name) \
- ASSERT((TraceIC(type, name), true))
IC::IC(FrameDepth depth, Isolate* isolate)
: isolate_(isolate),
uint32_t index;
if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
// Rewrite to the generic keyed load stub.
- if (FLAG_use_ic) set_target(*generic_stub());
+ if (FLAG_use_ic) {
+ set_target(*generic_stub());
+ TRACE_IC("LoadIC", name);
+ TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
+ }
Handle<Object> result;
ASSIGN_RETURN_ON_EXCEPTION(
isolate(),
bool is_target_set() { return target_set_; }
-#ifdef DEBUG
char TransitionMarkFromState(IC::State state);
-
void TraceIC(const char* type, Handle<Object> name);
-#endif
MaybeHandle<Object> TypeError(const char* type,
Handle<Object> object,