OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 } | 57 } |
58 UNREACHABLE(); | 58 UNREACHABLE(); |
59 return 0; | 59 return 0; |
60 } | 60 } |
61 | 61 |
62 void IC::TraceIC(const char* type, | 62 void IC::TraceIC(const char* type, |
63 Handle<Object> name, | 63 Handle<Object> name, |
64 State old_state, | 64 State old_state, |
65 Code* new_target) { | 65 Code* new_target) { |
66 if (FLAG_trace_ic) { | 66 if (FLAG_trace_ic) { |
67 State new_state = StateFrom(new_target, | 67 Object* undef = new_target->GetHeap()->undefined_value(); |
68 HEAP->undefined_value(), | 68 State new_state = StateFrom(new_target, undef, undef); |
69 HEAP->undefined_value()); | |
70 PrintF("[%s in ", type); | 69 PrintF("[%s in ", type); |
71 StackFrameIterator it; | 70 Isolate* isolate = new_target->GetIsolate(); |
| 71 StackFrameIterator it(isolate); |
72 while (it.frame()->fp() != this->fp()) it.Advance(); | 72 while (it.frame()->fp() != this->fp()) it.Advance(); |
73 StackFrame* raw_frame = it.frame(); | 73 StackFrame* raw_frame = it.frame(); |
74 if (raw_frame->is_internal()) { | 74 if (raw_frame->is_internal()) { |
75 Isolate* isolate = new_target->GetIsolate(); | |
76 Code* apply_builtin = isolate->builtins()->builtin( | 75 Code* apply_builtin = isolate->builtins()->builtin( |
77 Builtins::kFunctionApply); | 76 Builtins::kFunctionApply); |
78 if (raw_frame->unchecked_code() == apply_builtin) { | 77 if (raw_frame->unchecked_code() == apply_builtin) { |
79 PrintF("apply from "); | 78 PrintF("apply from "); |
80 it.Advance(); | 79 it.Advance(); |
81 raw_frame = it.frame(); | 80 raw_frame = it.frame(); |
82 } | 81 } |
83 } | 82 } |
84 JavaScriptFrame::PrintTop(stdout, false, true); | 83 JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
85 bool new_can_grow = | 84 bool new_can_grow = |
86 Code::GetKeyedAccessGrowMode(new_target->extra_ic_state()) == | 85 Code::GetKeyedAccessGrowMode(new_target->extra_ic_state()) == |
87 ALLOW_JSARRAY_GROWTH; | 86 ALLOW_JSARRAY_GROWTH; |
88 PrintF(" (%c->%c%s)", | 87 PrintF(" (%c->%c%s)", |
89 TransitionMarkFromState(old_state), | 88 TransitionMarkFromState(old_state), |
90 TransitionMarkFromState(new_state), | 89 TransitionMarkFromState(new_state), |
91 new_can_grow ? ".GROW" : ""); | 90 new_can_grow ? ".GROW" : ""); |
92 name->Print(); | 91 name->Print(); |
93 PrintF("]\n"); | 92 PrintF("]\n"); |
94 } | 93 } |
95 } | 94 } |
96 | 95 |
97 #define TRACE_GENERIC_IC(type, reason) \ | 96 #define TRACE_GENERIC_IC(isolate, type, reason) \ |
98 do { \ | 97 do { \ |
99 if (FLAG_trace_ic) { \ | 98 if (FLAG_trace_ic) { \ |
100 PrintF("[%s patching generic stub in ", type); \ | 99 PrintF("[%s patching generic stub in ", type); \ |
101 JavaScriptFrame::PrintTop(stdout, false, true); \ | 100 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \ |
102 PrintF(" (%s)]\n", reason); \ | 101 PrintF(" (%s)]\n", reason); \ |
103 } \ | 102 } \ |
104 } while (false) | 103 } while (false) |
105 | 104 |
106 #else | 105 #else |
107 #define TRACE_GENERIC_IC(type, reason) | 106 #define TRACE_GENERIC_IC(isolate, type, reason) |
108 #endif // DEBUG | 107 #endif // DEBUG |
109 | 108 |
110 #define TRACE_IC(type, name, old_state, new_target) \ | 109 #define TRACE_IC(type, name, old_state, new_target) \ |
111 ASSERT((TraceIC(type, name, old_state, new_target), true)) | 110 ASSERT((TraceIC(type, name, old_state, new_target), true)) |
112 | 111 |
113 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { | 112 IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) { |
114 // To improve the performance of the (much used) IC code, we unfold a few | 113 // To improve the performance of the (much used) IC code, we unfold a few |
115 // levels of the stack frame iteration code. This yields a ~35% speedup when | 114 // levels of the stack frame iteration code. This yields a ~35% speedup when |
116 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. | 115 // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. |
117 const Address entry = | 116 const Address entry = |
118 Isolate::c_entry_fp(isolate->thread_local_top()); | 117 Isolate::c_entry_fp(isolate->thread_local_top()); |
119 Address* pc_address = | 118 Address* pc_address = |
120 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); | 119 reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); |
121 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); | 120 Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); |
122 // If there's another JavaScript frame on the stack or a | 121 // If there's another JavaScript frame on the stack or a |
123 // StubFailureTrampoline, we need to look one frame further down the stack to | 122 // StubFailureTrampoline, we need to look one frame further down the stack to |
124 // find the frame pointer and the return address stack slot. | 123 // find the frame pointer and the return address stack slot. |
125 if (depth == EXTRA_CALL_FRAME) { | 124 if (depth == EXTRA_CALL_FRAME) { |
126 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; | 125 const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; |
127 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); | 126 pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); |
128 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); | 127 fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); |
129 } | 128 } |
130 #ifdef DEBUG | 129 #ifdef DEBUG |
131 StackFrameIterator it; | 130 StackFrameIterator it(isolate); |
132 for (int i = 0; i < depth + 1; i++) it.Advance(); | 131 for (int i = 0; i < depth + 1; i++) it.Advance(); |
133 StackFrame* frame = it.frame(); | 132 StackFrame* frame = it.frame(); |
134 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); | 133 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); |
135 #endif | 134 #endif |
136 fp_ = fp; | 135 fp_ = fp; |
137 pc_address_ = pc_address; | 136 pc_address_ = pc_address; |
138 } | 137 } |
139 | 138 |
140 | 139 |
141 #ifdef ENABLE_DEBUGGER_SUPPORT | 140 #ifdef ENABLE_DEBUGGER_SUPPORT |
142 Address IC::OriginalCodeAddress() const { | 141 Address IC::OriginalCodeAddress() const { |
143 HandleScope scope; | 142 HandleScope scope(isolate()); |
144 // Compute the JavaScript frame for the frame pointer of this IC | 143 // Compute the JavaScript frame for the frame pointer of this IC |
145 // structure. We need this to be able to find the function | 144 // structure. We need this to be able to find the function |
146 // corresponding to the frame. | 145 // corresponding to the frame. |
147 StackFrameIterator it; | 146 StackFrameIterator it(isolate()); |
148 while (it.frame()->fp() != this->fp()) it.Advance(); | 147 while (it.frame()->fp() != this->fp()) it.Advance(); |
149 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); | 148 JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); |
150 // Find the function on the stack and both the active code for the | 149 // Find the function on the stack and both the active code for the |
151 // function and the original code. | 150 // function and the original code. |
152 JSFunction* function = JSFunction::cast(frame->function()); | 151 JSFunction* function = JSFunction::cast(frame->function()); |
153 Handle<SharedFunctionInfo> shared(function->shared()); | 152 Handle<SharedFunctionInfo> shared(function->shared()); |
154 Code* code = shared->code(); | 153 Code* code = shared->code(); |
155 ASSERT(Debug::HasDebugInfo(shared)); | 154 ASSERT(Debug::HasDebugInfo(shared)); |
156 Code* original_code = Debug::GetDebugInfo(shared)->original_code(); | 155 Code* original_code = Debug::GetDebugInfo(shared)->original_code(); |
157 ASSERT(original_code->IsCode()); | 156 ASSERT(original_code->IsCode()); |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 } | 445 } |
447 | 446 |
448 | 447 |
449 Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { | 448 Handle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { |
450 Handle<Object> delegate = Execution::GetFunctionDelegate(object); | 449 Handle<Object> delegate = Execution::GetFunctionDelegate(object); |
451 | 450 |
452 if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) { | 451 if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) { |
453 // Patch the receiver and use the delegate as the function to | 452 // Patch the receiver and use the delegate as the function to |
454 // invoke. This is used for invoking objects as if they were functions. | 453 // invoke. This is used for invoking objects as if they were functions. |
455 const int argc = target()->arguments_count(); | 454 const int argc = target()->arguments_count(); |
456 StackFrameLocator locator; | 455 StackFrameLocator locator(isolate()); |
457 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 456 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
458 int index = frame->ComputeExpressionsCount() - (argc + 1); | 457 int index = frame->ComputeExpressionsCount() - (argc + 1); |
459 frame->SetExpression(index, *object); | 458 frame->SetExpression(index, *object); |
460 } | 459 } |
461 | 460 |
462 return delegate; | 461 return delegate; |
463 } | 462 } |
464 | 463 |
465 | 464 |
466 void CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee, | 465 void CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee, |
467 Handle<Object> object) { | 466 Handle<Object> object) { |
468 while (callee->IsJSFunctionProxy()) { | 467 while (callee->IsJSFunctionProxy()) { |
469 callee = Handle<Object>(JSFunctionProxy::cast(*callee)->call_trap()); | 468 callee = Handle<Object>(JSFunctionProxy::cast(*callee)->call_trap()); |
470 } | 469 } |
471 | 470 |
472 if (callee->IsJSFunction()) { | 471 if (callee->IsJSFunction()) { |
473 Handle<JSFunction> function = Handle<JSFunction>::cast(callee); | 472 Handle<JSFunction> function = Handle<JSFunction>::cast(callee); |
474 if (!function->shared()->is_classic_mode() || function->IsBuiltin()) { | 473 if (!function->shared()->is_classic_mode() || function->IsBuiltin()) { |
475 // Do not wrap receiver for strict mode functions or for builtins. | 474 // Do not wrap receiver for strict mode functions or for builtins. |
476 return; | 475 return; |
477 } | 476 } |
478 } | 477 } |
479 | 478 |
480 // And only wrap string, number or boolean. | 479 // And only wrap string, number or boolean. |
481 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { | 480 if (object->IsString() || object->IsNumber() || object->IsBoolean()) { |
482 // Change the receiver to the result of calling ToObject on it. | 481 // Change the receiver to the result of calling ToObject on it. |
483 const int argc = this->target()->arguments_count(); | 482 const int argc = this->target()->arguments_count(); |
484 StackFrameLocator locator; | 483 StackFrameLocator locator(isolate()); |
485 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 484 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
486 int index = frame->ComputeExpressionsCount() - (argc + 1); | 485 int index = frame->ComputeExpressionsCount() - (argc + 1); |
487 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); | 486 frame->SetExpression(index, *isolate()->factory()->ToObject(object)); |
488 } | 487 } |
489 } | 488 } |
490 | 489 |
491 | 490 |
492 MaybeObject* CallICBase::LoadFunction(State state, | 491 MaybeObject* CallICBase::LoadFunction(State state, |
493 Code::ExtraICState extra_ic_state, | 492 Code::ExtraICState extra_ic_state, |
494 Handle<Object> object, | 493 Handle<Object> object, |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1155 } | 1154 } |
1156 | 1155 |
1157 | 1156 |
1158 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { | 1157 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { |
1159 State ic_state = target()->ic_state(); | 1158 State ic_state = target()->ic_state(); |
1160 | 1159 |
1161 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 1160 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
1162 // via megamorphic stubs, since they don't have a map in their relocation info | 1161 // via megamorphic stubs, since they don't have a map in their relocation info |
1163 // and so the stubs can't be harvested for the object needed for a map check. | 1162 // and so the stubs can't be harvested for the object needed for a map check. |
1164 if (target()->type() != Code::NORMAL) { | 1163 if (target()->type() != Code::NORMAL) { |
1165 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); | 1164 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); |
1166 return generic_stub(); | 1165 return generic_stub(); |
1167 } | 1166 } |
1168 | 1167 |
1169 Handle<Map> receiver_map(receiver->map()); | 1168 Handle<Map> receiver_map(receiver->map()); |
1170 MapHandleList target_receiver_maps; | 1169 MapHandleList target_receiver_maps; |
1171 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | 1170 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
1172 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1171 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
1173 // yet will do so and stay there. | 1172 // yet will do so and stay there. |
1174 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); | 1173 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); |
1175 } | 1174 } |
(...skipping 21 matching lines...) Expand all Loading... |
1197 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); | 1196 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); |
1198 } | 1197 } |
1199 | 1198 |
1200 ASSERT(ic_state != GENERIC); | 1199 ASSERT(ic_state != GENERIC); |
1201 | 1200 |
1202 // Determine the list of receiver maps that this call site has seen, | 1201 // Determine the list of receiver maps that this call site has seen, |
1203 // adding the map that was just encountered. | 1202 // adding the map that was just encountered. |
1204 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { | 1203 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { |
1205 // If the miss wasn't due to an unseen map, a polymorphic stub | 1204 // If the miss wasn't due to an unseen map, a polymorphic stub |
1206 // won't help, use the generic stub. | 1205 // won't help, use the generic stub. |
1207 TRACE_GENERIC_IC("KeyedIC", "same map added twice"); | 1206 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); |
1208 return generic_stub(); | 1207 return generic_stub(); |
1209 } | 1208 } |
1210 | 1209 |
1211 // If the maximum number of receiver maps has been exceeded, use the generic | 1210 // If the maximum number of receiver maps has been exceeded, use the generic |
1212 // version of the IC. | 1211 // version of the IC. |
1213 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { | 1212 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { |
1214 TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded"); | 1213 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); |
1215 return generic_stub(); | 1214 return generic_stub(); |
1216 } | 1215 } |
1217 | 1216 |
1218 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( | 1217 return isolate()->stub_cache()->ComputeLoadElementPolymorphic( |
1219 &target_receiver_maps); | 1218 &target_receiver_maps); |
1220 } | 1219 } |
1221 | 1220 |
1222 | 1221 |
1223 MaybeObject* KeyedLoadIC::Load(State state, | 1222 MaybeObject* KeyedLoadIC::Load(State state, |
1224 Handle<Object> object, | 1223 Handle<Object> object, |
(...skipping 22 matching lines...) Expand all Loading... |
1247 if (receiver->elements()->map() == | 1246 if (receiver->elements()->map() == |
1248 isolate()->heap()->non_strict_arguments_elements_map()) { | 1247 isolate()->heap()->non_strict_arguments_elements_map()) { |
1249 stub = non_strict_arguments_stub(); | 1248 stub = non_strict_arguments_stub(); |
1250 } else if (receiver->HasIndexedInterceptor()) { | 1249 } else if (receiver->HasIndexedInterceptor()) { |
1251 stub = indexed_interceptor_stub(); | 1250 stub = indexed_interceptor_stub(); |
1252 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { | 1251 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { |
1253 stub = LoadElementStub(receiver); | 1252 stub = LoadElementStub(receiver); |
1254 } | 1253 } |
1255 } | 1254 } |
1256 } else { | 1255 } else { |
1257 TRACE_GENERIC_IC("KeyedLoadIC", "force generic"); | 1256 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "force generic"); |
1258 } | 1257 } |
1259 ASSERT(!stub.is_null()); | 1258 ASSERT(!stub.is_null()); |
1260 set_target(*stub); | 1259 set_target(*stub); |
1261 TRACE_IC("KeyedLoadIC", key, state, target()); | 1260 TRACE_IC("KeyedLoadIC", key, state, target()); |
1262 } | 1261 } |
1263 | 1262 |
1264 | 1263 |
1265 return Runtime::GetObjectProperty(isolate(), object, key); | 1264 return Runtime::GetObjectProperty(isolate(), object, key); |
1266 } | 1265 } |
1267 | 1266 |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1535 StrictModeFlag strict_mode) { | 1534 StrictModeFlag strict_mode) { |
1536 State ic_state = target()->ic_state(); | 1535 State ic_state = target()->ic_state(); |
1537 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind) | 1536 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind) |
1538 ? ALLOW_JSARRAY_GROWTH | 1537 ? ALLOW_JSARRAY_GROWTH |
1539 : DO_NOT_ALLOW_JSARRAY_GROWTH; | 1538 : DO_NOT_ALLOW_JSARRAY_GROWTH; |
1540 | 1539 |
1541 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 1540 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |
1542 // via megamorphic stubs, since they don't have a map in their relocation info | 1541 // via megamorphic stubs, since they don't have a map in their relocation info |
1543 // and so the stubs can't be harvested for the object needed for a map check. | 1542 // and so the stubs can't be harvested for the object needed for a map check. |
1544 if (target()->type() != Code::NORMAL) { | 1543 if (target()->type() != Code::NORMAL) { |
1545 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); | 1544 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); |
1546 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); | 1545 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); |
1547 } | 1546 } |
1548 | 1547 |
1549 Handle<Map> receiver_map(receiver->map()); | 1548 Handle<Map> receiver_map(receiver->map()); |
1550 MapHandleList target_receiver_maps; | 1549 MapHandleList target_receiver_maps; |
1551 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | 1550 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
1552 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 1551 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state |
1553 // yet will do so and stay there. | 1552 // yet will do so and stay there. |
1554 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); | 1553 Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); |
1555 stub_kind = GetNoTransitionStubKind(stub_kind); | 1554 stub_kind = GetNoTransitionStubKind(stub_kind); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1590 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1589 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
1591 | 1590 |
1592 if (IsTransitionStubKind(stub_kind)) { | 1591 if (IsTransitionStubKind(stub_kind)) { |
1593 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); | 1592 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); |
1594 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); | 1593 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); |
1595 } | 1594 } |
1596 | 1595 |
1597 if (!map_added) { | 1596 if (!map_added) { |
1598 // If the miss wasn't due to an unseen map, a polymorphic stub | 1597 // If the miss wasn't due to an unseen map, a polymorphic stub |
1599 // won't help, use the generic stub. | 1598 // won't help, use the generic stub. |
1600 TRACE_GENERIC_IC("KeyedIC", "same map added twice"); | 1599 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); |
1601 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); | 1600 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); |
1602 } | 1601 } |
1603 | 1602 |
1604 // If the maximum number of receiver maps has been exceeded, use the generic | 1603 // If the maximum number of receiver maps has been exceeded, use the generic |
1605 // version of the IC. | 1604 // version of the IC. |
1606 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { | 1605 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { |
1607 TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded"); | 1606 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); |
1608 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); | 1607 return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub(); |
1609 } | 1608 } |
1610 | 1609 |
1611 if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) == | 1610 if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) == |
1612 ALLOW_JSARRAY_GROWTH)) { | 1611 ALLOW_JSARRAY_GROWTH)) { |
1613 grow_mode = ALLOW_JSARRAY_GROWTH; | 1612 grow_mode = ALLOW_JSARRAY_GROWTH; |
1614 } | 1613 } |
1615 | 1614 |
1616 return isolate()->stub_cache()->ComputeStoreElementPolymorphic( | 1615 return isolate()->stub_cache()->ComputeStoreElementPolymorphic( |
1617 &target_receiver_maps, grow_mode, strict_mode); | 1616 &target_receiver_maps, grow_mode, strict_mode); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1745 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
1747 if (receiver->elements()->map() == | 1746 if (receiver->elements()->map() == |
1748 isolate()->heap()->non_strict_arguments_elements_map()) { | 1747 isolate()->heap()->non_strict_arguments_elements_map()) { |
1749 stub = non_strict_arguments_stub(); | 1748 stub = non_strict_arguments_stub(); |
1750 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { | 1749 } else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { |
1751 StubKind stub_kind = GetStubKind(receiver, key, value); | 1750 StubKind stub_kind = GetStubKind(receiver, key, value); |
1752 stub = StoreElementStub(receiver, stub_kind, strict_mode); | 1751 stub = StoreElementStub(receiver, stub_kind, strict_mode); |
1753 } | 1752 } |
1754 } | 1753 } |
1755 } else { | 1754 } else { |
1756 TRACE_GENERIC_IC("KeyedStoreIC", "force generic"); | 1755 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "force generic"); |
1757 } | 1756 } |
1758 ASSERT(!stub.is_null()); | 1757 ASSERT(!stub.is_null()); |
1759 set_target(*stub); | 1758 set_target(*stub); |
1760 TRACE_IC("KeyedStoreIC", key, state, target()); | 1759 TRACE_IC("KeyedStoreIC", key, state, target()); |
1761 } | 1760 } |
1762 | 1761 |
1763 return Runtime::SetObjectProperty( | 1762 return Runtime::SetObjectProperty( |
1764 isolate(), object , key, value, NONE, strict_mode); | 1763 isolate(), object , key, value, NONE, strict_mode); |
1765 } | 1764 } |
1766 | 1765 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1899 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1898 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
1900 return ic.Load(state, | 1899 return ic.Load(state, |
1901 args.at<Object>(0), | 1900 args.at<Object>(0), |
1902 args.at<Object>(1), | 1901 args.at<Object>(1), |
1903 MISS_FORCE_GENERIC); | 1902 MISS_FORCE_GENERIC); |
1904 } | 1903 } |
1905 | 1904 |
1906 | 1905 |
1907 // Used from ic-<arch>.cc. | 1906 // Used from ic-<arch>.cc. |
1908 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { | 1907 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { |
1909 HandleScope scope; | 1908 HandleScope scope(isolate); |
1910 ASSERT(args.length() == 3); | 1909 ASSERT(args.length() == 3); |
1911 StoreIC ic(isolate); | 1910 StoreIC ic(isolate); |
1912 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 1911 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
1913 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); | 1912 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); |
1914 return ic.Store(state, | 1913 return ic.Store(state, |
1915 Code::GetStrictMode(extra_ic_state), | 1914 Code::GetStrictMode(extra_ic_state), |
1916 args.at<Object>(0), | 1915 args.at<Object>(0), |
1917 args.at<String>(1), | 1916 args.at<String>(1), |
1918 args.at<Object>(2)); | 1917 args.at<Object>(2)); |
1919 } | 1918 } |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2142 static_cast<UnaryOpIC::TypeInfo>(args.smi_at(3)); | 2141 static_cast<UnaryOpIC::TypeInfo>(args.smi_at(3)); |
2143 | 2142 |
2144 UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand); | 2143 UnaryOpIC::TypeInfo type = UnaryOpIC::GetTypeInfo(operand); |
2145 type = UnaryOpIC::ComputeNewType(type, previous_type); | 2144 type = UnaryOpIC::ComputeNewType(type, previous_type); |
2146 | 2145 |
2147 UnaryOpStub stub(op, mode, type); | 2146 UnaryOpStub stub(op, mode, type); |
2148 Handle<Code> code = stub.GetCode(); | 2147 Handle<Code> code = stub.GetCode(); |
2149 if (!code.is_null()) { | 2148 if (!code.is_null()) { |
2150 if (FLAG_trace_ic) { | 2149 if (FLAG_trace_ic) { |
2151 PrintF("[UnaryOpIC in "); | 2150 PrintF("[UnaryOpIC in "); |
2152 JavaScriptFrame::PrintTop(stdout, false, true); | 2151 JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
2153 PrintF(" (%s->%s)#%s @ %p]\n", | 2152 PrintF(" (%s->%s)#%s @ %p]\n", |
2154 UnaryOpIC::GetName(previous_type), | 2153 UnaryOpIC::GetName(previous_type), |
2155 UnaryOpIC::GetName(type), | 2154 UnaryOpIC::GetName(type), |
2156 Token::Name(op), | 2155 Token::Name(op), |
2157 static_cast<void*>(*code)); | 2156 static_cast<void*>(*code)); |
2158 } | 2157 } |
2159 UnaryOpIC ic(isolate); | 2158 UnaryOpIC ic(isolate); |
2160 ic.patch(*code); | 2159 ic.patch(*code); |
2161 } | 2160 } |
2162 | 2161 |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2271 result_type = BinaryOpIC::HEAP_NUMBER; | 2270 result_type = BinaryOpIC::HEAP_NUMBER; |
2272 } | 2271 } |
2273 } | 2272 } |
2274 | 2273 |
2275 BinaryOpStub stub(key, new_left, new_right, result_type); | 2274 BinaryOpStub stub(key, new_left, new_right, result_type); |
2276 Handle<Code> code = stub.GetCode(); | 2275 Handle<Code> code = stub.GetCode(); |
2277 if (!code.is_null()) { | 2276 if (!code.is_null()) { |
2278 #ifdef DEBUG | 2277 #ifdef DEBUG |
2279 if (FLAG_trace_ic) { | 2278 if (FLAG_trace_ic) { |
2280 PrintF("[BinaryOpIC in "); | 2279 PrintF("[BinaryOpIC in "); |
2281 JavaScriptFrame::PrintTop(stdout, false, true); | 2280 JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
2282 PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n", | 2281 PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n", |
2283 BinaryOpIC::GetName(previous_left), | 2282 BinaryOpIC::GetName(previous_left), |
2284 BinaryOpIC::GetName(previous_right), | 2283 BinaryOpIC::GetName(previous_right), |
2285 BinaryOpIC::GetName(new_left), | 2284 BinaryOpIC::GetName(new_left), |
2286 BinaryOpIC::GetName(new_right), | 2285 BinaryOpIC::GetName(new_right), |
2287 BinaryOpIC::GetName(result_type), | 2286 BinaryOpIC::GetName(result_type), |
2288 Token::Name(op), | 2287 Token::Name(op), |
2289 static_cast<void*>(*code)); | 2288 static_cast<void*>(*code)); |
2290 } | 2289 } |
2291 #endif | 2290 #endif |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2473 case KNOWN_OBJECTS: | 2472 case KNOWN_OBJECTS: |
2474 case GENERIC: | 2473 case GENERIC: |
2475 return GENERIC; | 2474 return GENERIC; |
2476 } | 2475 } |
2477 UNREACHABLE(); | 2476 UNREACHABLE(); |
2478 return GENERIC; // Make the compiler happy. | 2477 return GENERIC; // Make the compiler happy. |
2479 } | 2478 } |
2480 | 2479 |
2481 | 2480 |
2482 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { | 2481 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { |
2483 HandleScope scope; | 2482 HandleScope scope(isolate()); |
2484 State previous_left, previous_right, previous_state; | 2483 State previous_left, previous_right, previous_state; |
2485 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, | 2484 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, |
2486 &previous_right, &previous_state, NULL); | 2485 &previous_right, &previous_state, NULL); |
2487 State new_left = InputState(previous_left, x); | 2486 State new_left = InputState(previous_left, x); |
2488 State new_right = InputState(previous_right, y); | 2487 State new_right = InputState(previous_right, y); |
2489 State state = TargetState(previous_state, previous_left, previous_right, | 2488 State state = TargetState(previous_state, previous_left, previous_right, |
2490 HasInlinedSmiCode(address()), x, y); | 2489 HasInlinedSmiCode(address()), x, y); |
2491 ICCompareStub stub(op_, new_left, new_right, state); | 2490 ICCompareStub stub(op_, new_left, new_right, state); |
2492 if (state == KNOWN_OBJECTS) { | 2491 if (state == KNOWN_OBJECTS) { |
2493 stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map())); | 2492 stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map())); |
2494 } | 2493 } |
2495 set_target(*stub.GetCode()); | 2494 set_target(*stub.GetCode()); |
2496 | 2495 |
2497 #ifdef DEBUG | 2496 #ifdef DEBUG |
2498 if (FLAG_trace_ic) { | 2497 if (FLAG_trace_ic) { |
2499 PrintF("[CompareIC in "); | 2498 PrintF("[CompareIC in "); |
2500 JavaScriptFrame::PrintTop(stdout, false, true); | 2499 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); |
2501 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", | 2500 PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", |
2502 GetStateName(previous_left), | 2501 GetStateName(previous_left), |
2503 GetStateName(previous_right), | 2502 GetStateName(previous_right), |
2504 GetStateName(previous_state), | 2503 GetStateName(previous_state), |
2505 GetStateName(new_left), | 2504 GetStateName(new_left), |
2506 GetStateName(new_right), | 2505 GetStateName(new_right), |
2507 GetStateName(state), | 2506 GetStateName(state), |
2508 Token::Name(op_), | 2507 Token::Name(op_), |
2509 static_cast<void*>(*stub.GetCode())); | 2508 static_cast<void*>(*stub.GetCode())); |
2510 } | 2509 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2559 #undef ADDR | 2558 #undef ADDR |
2560 }; | 2559 }; |
2561 | 2560 |
2562 | 2561 |
2563 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2562 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2564 return IC_utilities[id]; | 2563 return IC_utilities[id]; |
2565 } | 2564 } |
2566 | 2565 |
2567 | 2566 |
2568 } } // namespace v8::internal | 2567 } } // namespace v8::internal |
OLD | NEW |