Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: src/ic.cc

Issue 8803013: Improve TraceIC logging (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 22 matching lines...) Expand all
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "execution.h" 34 #include "execution.h"
35 #include "ic-inl.h" 35 #include "ic-inl.h"
36 #include "runtime.h" 36 #include "runtime.h"
37 #include "stub-cache.h" 37 #include "stub-cache.h"
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 #ifdef DEBUG 42 #ifdef DEBUG
43 static char TransitionMarkFromState(IC::State state) { 43 char IC::TransitionMarkFromState(IC::State state) {
44 switch (state) { 44 switch (state) {
45 case UNINITIALIZED: return '0'; 45 case UNINITIALIZED: return '0';
46 case PREMONOMORPHIC: return 'P'; 46 case PREMONOMORPHIC: return 'P';
47 case MONOMORPHIC: return '1'; 47 case MONOMORPHIC: return '1';
48 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; 48 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
49 case MEGAMORPHIC: return 'N'; 49 case MEGAMORPHIC: return IsGeneric() ? 'G' : 'N';
50 50
51 // We never see the debugger states here, because the state is 51 // We never see the debugger states here, because the state is
52 // computed from the original code - not the patched code. Let 52 // computed from the original code - not the patched code. Let
53 // these cases fall through to the unreachable code below. 53 // these cases fall through to the unreachable code below.
54 case DEBUG_BREAK: break; 54 case DEBUG_BREAK: break;
55 case DEBUG_PREPARE_STEP_IN: break; 55 case DEBUG_PREPARE_STEP_IN: break;
56 } 56 }
57 UNREACHABLE(); 57 UNREACHABLE();
58 return 0; 58 return 0;
59 } 59 }
(...skipping 13 matching lines...) Expand all
73 if (raw_frame->is_internal()) { 73 if (raw_frame->is_internal()) {
74 Isolate* isolate = new_target->GetIsolate(); 74 Isolate* isolate = new_target->GetIsolate();
75 Code* apply_builtin = isolate->builtins()->builtin( 75 Code* apply_builtin = isolate->builtins()->builtin(
76 Builtins::kFunctionApply); 76 Builtins::kFunctionApply);
77 if (raw_frame->unchecked_code() == apply_builtin) { 77 if (raw_frame->unchecked_code() == apply_builtin) {
78 PrintF("apply from "); 78 PrintF("apply from ");
79 it.Advance(); 79 it.Advance();
80 raw_frame = it.frame(); 80 raw_frame = it.frame();
81 } 81 }
82 } 82 }
83 if (raw_frame->is_java_script()) { 83 JavaScriptFrame::PrintTop(stdout, false, true);
84 JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
85 Code* js_code = frame->unchecked_code();
86 // Find the function on the stack and both the active code for the
87 // function and the original code.
88 JSFunction* function = JSFunction::cast(frame->function());
89 function->PrintName();
90 int code_offset =
91 static_cast<int>(address() - js_code->instruction_start());
92 PrintF("+%d", code_offset);
93 } else {
94 PrintF("<unknown>");
95 }
96 PrintF(" (%c->%c)", 84 PrintF(" (%c->%c)",
97 TransitionMarkFromState(old_state), 85 TransitionMarkFromState(old_state),
98 TransitionMarkFromState(new_state)); 86 TransitionMarkFromState(new_state));
99 name->Print(); 87 name->Print();
100 PrintF("]\n"); 88 PrintF("]\n");
101 } 89 }
102 } 90 }
91
92 #define TRACE_GENERIC_IC(type, reason) \
93 do { \
94 if (FLAG_trace_ic) { \
95 PrintF("[%s patching generic stub in ", type); \
96 JavaScriptFrame::PrintTop(stdout, false, true); \
97 PrintF(" (%s)]\n", reason); \
98 } \
99 } while (false)
100
101 #else
102 #define TRACE_GENERIC_IC(type, reason)
103 #endif // DEBUG 103 #endif // DEBUG
104 104
105
106 #define TRACE_IC(type, name, old_state, new_target) \ 105 #define TRACE_IC(type, name, old_state, new_target) \
107 ASSERT((TraceIC(type, name, old_state, new_target), true)) 106 ASSERT((TraceIC(type, name, old_state, new_target), true))
108 107
109
110 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { 108 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
111 ASSERT(isolate == Isolate::Current()); 109 ASSERT(isolate == Isolate::Current());
112 // To improve the performance of the (much used) IC code, we unfold 110 // To improve the performance of the (much used) IC code, we unfold
113 // a few levels of the stack frame iteration code. This yields a 111 // a few levels of the stack frame iteration code. This yields a
114 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag. 112 // ~35% speedup when running DeltaBlue with the '--nouse-ic' flag.
115 const Address entry = 113 const Address entry =
116 Isolate::c_entry_fp(isolate->thread_local_top()); 114 Isolate::c_entry_fp(isolate->thread_local_top());
117 Address* pc_address = 115 Address* pc_address =
118 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); 116 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
119 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 117 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
(...skipping 10 matching lines...) Expand all
130 for (int i = 0; i < depth + 1; i++) it.Advance(); 128 for (int i = 0; i < depth + 1; i++) it.Advance();
131 StackFrame* frame = it.frame(); 129 StackFrame* frame = it.frame();
132 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); 130 ASSERT(fp == frame->fp() && pc_address == frame->pc_address());
133 #endif 131 #endif
134 fp_ = fp; 132 fp_ = fp;
135 pc_address_ = pc_address; 133 pc_address_ = pc_address;
136 } 134 }
137 135
138 136
139 #ifdef ENABLE_DEBUGGER_SUPPORT 137 #ifdef ENABLE_DEBUGGER_SUPPORT
140 Address IC::OriginalCodeAddress() { 138 Address IC::OriginalCodeAddress() const {
141 HandleScope scope; 139 HandleScope scope;
142 // Compute the JavaScript frame for the frame pointer of this IC 140 // Compute the JavaScript frame for the frame pointer of this IC
143 // structure. We need this to be able to find the function 141 // structure. We need this to be able to find the function
144 // corresponding to the frame. 142 // corresponding to the frame.
145 StackFrameIterator it; 143 StackFrameIterator it;
146 while (it.frame()->fp() != this->fp()) it.Advance(); 144 while (it.frame()->fp() != this->fp()) it.Advance();
147 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); 145 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame());
148 // Find the function on the stack and both the active code for the 146 // Find the function on the stack and both the active code for the
149 // function and the original code. 147 // function and the original code.
150 JSFunction* function = JSFunction::cast(frame->function()); 148 JSFunction* function = JSFunction::cast(frame->function());
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1114 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1117 if (receiver->elements()->map() == 1115 if (receiver->elements()->map() ==
1118 isolate()->heap()->non_strict_arguments_elements_map()) { 1116 isolate()->heap()->non_strict_arguments_elements_map()) {
1119 stub = non_strict_arguments_stub(); 1117 stub = non_strict_arguments_stub();
1120 } else if (receiver->HasIndexedInterceptor()) { 1118 } else if (receiver->HasIndexedInterceptor()) {
1121 stub = indexed_interceptor_stub(); 1119 stub = indexed_interceptor_stub();
1122 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1120 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1123 stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub); 1121 stub = ComputeStub(receiver, LOAD, kNonStrictMode, stub);
1124 } 1122 }
1125 } 1123 }
1124 } else {
1125 TRACE_GENERIC_IC("KeyedLoadIC", "force generic");
1126 } 1126 }
1127 if (!stub.is_null()) set_target(*stub); 1127 if (!stub.is_null()) set_target(*stub);
1128 } 1128 }
1129 1129
1130 TRACE_IC("KeyedLoadIC", key, state, target()); 1130 TRACE_IC("KeyedLoadIC", key, state, target());
1131 1131
1132 // Get the property. 1132 // Get the property.
1133 return Runtime::GetObjectProperty(isolate(), object, key); 1133 return Runtime::GetObjectProperty(isolate(), object, key);
1134 } 1134 }
1135 1135
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 !IsTransitionStubKind(stub_kind)) { 1466 !IsTransitionStubKind(stub_kind)) {
1467 return ComputeMonomorphicStub( 1467 return ComputeMonomorphicStub(
1468 receiver, stub_kind, strict_mode, generic_stub); 1468 receiver, stub_kind, strict_mode, generic_stub);
1469 } 1469 }
1470 ASSERT(target() != *generic_stub); 1470 ASSERT(target() != *generic_stub);
1471 1471
1472 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1472 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1473 // via megamorphic stubs, since they don't have a map in their relocation info 1473 // via megamorphic stubs, since they don't have a map in their relocation info
1474 // and so the stubs can't be harvested for the object needed for a map check. 1474 // and so the stubs can't be harvested for the object needed for a map check.
1475 if (target()->type() != NORMAL) { 1475 if (target()->type() != NORMAL) {
1476 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
1476 return generic_stub; 1477 return generic_stub;
1477 } 1478 }
1478 1479
1479 // Determine the list of receiver maps that this call site has seen, 1480 // Determine the list of receiver maps that this call site has seen,
1480 // adding the map that was just encountered. 1481 // adding the map that was just encountered.
1481 MapHandleList target_receiver_maps; 1482 MapHandleList target_receiver_maps;
1482 Handle<Map> receiver_map(receiver->map()); 1483 Handle<Map> receiver_map(receiver->map());
1483 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1484 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1484 target_receiver_maps.Add(receiver_map); 1485 target_receiver_maps.Add(receiver_map);
1485 } else { 1486 } else {
1486 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); 1487 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1487 } 1488 }
1488 bool map_added = 1489 bool map_added =
1489 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1490 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1490 if (IsTransitionStubKind(stub_kind)) { 1491 if (IsTransitionStubKind(stub_kind)) {
1491 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); 1492 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind);
1492 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); 1493 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
1493 } 1494 }
1494 if (!map_added) { 1495 if (!map_added) {
1495 // If the miss wasn't due to an unseen map, a polymorphic stub 1496 // If the miss wasn't due to an unseen map, a polymorphic stub
1496 // won't help, use the generic stub. 1497 // won't help, use the generic stub.
1498 TRACE_GENERIC_IC("KeyedIC", "same map added twice");
1497 return generic_stub; 1499 return generic_stub;
1498 } 1500 }
1499 1501
1500 // If the maximum number of receiver maps has been exceeded, use the generic 1502 // If the maximum number of receiver maps has been exceeded, use the generic
1501 // version of the IC. 1503 // version of the IC.
1502 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1504 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1505 TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
1503 return generic_stub; 1506 return generic_stub;
1504 } 1507 }
1505 1508
1506 Handle<PolymorphicCodeCache> cache = 1509 Handle<PolymorphicCodeCache> cache =
1507 isolate()->factory()->polymorphic_code_cache(); 1510 isolate()->factory()->polymorphic_code_cache();
1508 Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, strict_mode); 1511 Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, strict_mode);
1509 Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags); 1512 Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
1510 if (probe->IsCode()) return Handle<Code>::cast(probe); 1513 if (probe->IsCode()) return Handle<Code>::cast(probe);
1511 1514
1512 Handle<Code> stub = 1515 Handle<Code> stub =
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 } else if (value->IsHeapObject()) { 1681 } else if (value->IsHeapObject()) {
1679 stub_kind = STORE_TRANSITION_SMI_TO_OBJECT; 1682 stub_kind = STORE_TRANSITION_SMI_TO_OBJECT;
1680 } 1683 }
1681 } else if (receiver->GetElementsKind() == FAST_DOUBLE_ELEMENTS) { 1684 } else if (receiver->GetElementsKind() == FAST_DOUBLE_ELEMENTS) {
1682 if (!value->IsSmi() && !value->IsHeapNumber()) { 1685 if (!value->IsSmi() && !value->IsHeapNumber()) {
1683 stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT; 1686 stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT;
1684 } 1687 }
1685 } 1688 }
1686 stub = ComputeStub(receiver, stub_kind, strict_mode, stub); 1689 stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
1687 } 1690 }
1691 } else {
1692 TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
1688 } 1693 }
1689 } 1694 }
1690 if (!stub.is_null()) set_target(*stub); 1695 if (!stub.is_null()) set_target(*stub);
1691 } 1696 }
1692 1697
1693 TRACE_IC("KeyedStoreIC", key, state, target()); 1698 TRACE_IC("KeyedStoreIC", key, state, target());
1694 1699
1695 // Set the property. 1700 // Set the property.
1696 return Runtime::SetObjectProperty( 1701 return Runtime::SetObjectProperty(
1697 isolate(), object , key, value, NONE, strict_mode); 1702 isolate(), object , key, value, NONE, strict_mode);
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 #undef ADDR 2393 #undef ADDR
2389 }; 2394 };
2390 2395
2391 2396
2392 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2397 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2393 return IC_utilities[id]; 2398 return IC_utilities[id];
2394 } 2399 }
2395 2400
2396 2401
2397 } } // namespace v8::internal 2402 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698