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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 #ifdef DEBUG | 140 #ifdef DEBUG |
141 StackFrameIterator it(isolate); | 141 StackFrameIterator it(isolate); |
142 for (int i = 0; i < depth + 1; i++) it.Advance(); | 142 for (int i = 0; i < depth + 1; i++) it.Advance(); |
143 StackFrame* frame = it.frame(); | 143 StackFrame* frame = it.frame(); |
144 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); | 144 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); |
145 #endif | 145 #endif |
146 fp_ = fp; | 146 fp_ = fp; |
147 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); | 147 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); |
148 target_ = handle(raw_target(), isolate); | 148 target_ = handle(raw_target(), isolate); |
149 state_ = target_->ic_state(); | 149 state_ = target_->ic_state(); |
| 150 extra_ic_state_ = target_->needs_extended_extra_ic_state(target_->kind()) |
| 151 ? target_->extended_extra_ic_state() |
| 152 : target_->extra_ic_state(); |
150 } | 153 } |
151 | 154 |
152 | 155 |
153 #ifdef ENABLE_DEBUGGER_SUPPORT | 156 #ifdef ENABLE_DEBUGGER_SUPPORT |
154 Address IC::OriginalCodeAddress() const { | 157 Address IC::OriginalCodeAddress() const { |
155 HandleScope scope(isolate()); | 158 HandleScope scope(isolate()); |
156 // Compute the JavaScript frame for the frame pointer of this IC | 159 // Compute the JavaScript frame for the frame pointer of this IC |
157 // structure. We need this to be able to find the function | 160 // structure. We need this to be able to find the function |
158 // corresponding to the frame. | 161 // corresponding to the frame. |
159 StackFrameIterator it(isolate()); | 162 StackFrameIterator it(isolate()); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 if (object->IsString()) { | 250 if (object->IsString()) { |
248 String* string = String::cast(*object); | 251 String* string = String::cast(*object); |
249 // Check there's the right string value or wrapper in the receiver slot. | 252 // Check there's the right string value or wrapper in the receiver slot. |
250 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); | 253 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); |
251 // If we're in the default (fastest) state and the index is | 254 // If we're in the default (fastest) state and the index is |
252 // out of bounds, update the state to record this fact. | 255 // out of bounds, update the state to record this fact. |
253 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB && | 256 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB && |
254 argc >= 1 && args[1]->IsNumber()) { | 257 argc >= 1 && args[1]->IsNumber()) { |
255 double index = DoubleToInteger(args.number_at(1)); | 258 double index = DoubleToInteger(args.number_at(1)); |
256 if (index < 0 || index >= string->length()) { | 259 if (index < 0 || index >= string->length()) { |
257 extra_ic_state_ = | 260 set_extra_ic_state(StringStubState::update(extra_ic_state(), |
258 StringStubState::update(extra_ic_state(), | 261 STRING_INDEX_OUT_OF_BOUNDS)); |
259 STRING_INDEX_OUT_OF_BOUNDS); | |
260 return true; | 262 return true; |
261 } | 263 } |
262 } | 264 } |
263 } | 265 } |
264 break; | 266 break; |
265 default: | 267 default: |
266 return false; | 268 return false; |
267 } | 269 } |
268 return false; | 270 return false; |
269 } | 271 } |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 // The builtins object is special. It only changes when JavaScript | 392 // The builtins object is special. It only changes when JavaScript |
391 // builtins are loaded lazily. It is important to keep inline | 393 // builtins are loaded lazily. It is important to keep inline |
392 // caches for the builtins object monomorphic. Therefore, if we get | 394 // caches for the builtins object monomorphic. Therefore, if we get |
393 // an inline cache miss for the builtins object after lazily loading | 395 // an inline cache miss for the builtins object after lazily loading |
394 // JavaScript builtins, we return uninitialized as the state to | 396 // JavaScript builtins, we return uninitialized as the state to |
395 // force the inline cache back to monomorphic state. | 397 // force the inline cache back to monomorphic state. |
396 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; | 398 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; |
397 } | 399 } |
398 | 400 |
399 | 401 |
400 RelocInfo::Mode IC::ComputeMode() { | |
401 Address addr = address(); | |
402 Code* code = Code::cast(isolate()->FindCodeObject(addr)); | |
403 for (RelocIterator it(code, RelocInfo::kCodeTargetMask); | |
404 !it.done(); it.next()) { | |
405 RelocInfo* info = it.rinfo(); | |
406 if (info->pc() == addr) return info->rmode(); | |
407 } | |
408 UNREACHABLE(); | |
409 return RelocInfo::NONE32; | |
410 } | |
411 | |
412 | |
413 Failure* IC::TypeError(const char* type, | 402 Failure* IC::TypeError(const char* type, |
414 Handle<Object> object, | 403 Handle<Object> object, |
415 Handle<Object> key) { | 404 Handle<Object> key) { |
416 HandleScope scope(isolate()); | 405 HandleScope scope(isolate()); |
417 Handle<Object> args[2] = { key, object }; | 406 Handle<Object> args[2] = { key, object }; |
418 Handle<Object> error = isolate()->factory()->NewTypeError( | 407 Handle<Object> error = isolate()->factory()->NewTypeError( |
419 type, HandleVector(args, 2)); | 408 type, HandleVector(args, 2)); |
420 return isolate()->Throw(*error); | 409 return isolate()->Throw(*error); |
421 } | 410 } |
422 | 411 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 // Clearing these is tricky and does not | 481 // Clearing these is tricky and does not |
493 // make any performance difference. | 482 // make any performance difference. |
494 return; | 483 return; |
495 default: UNREACHABLE(); | 484 default: UNREACHABLE(); |
496 } | 485 } |
497 } | 486 } |
498 | 487 |
499 | 488 |
500 void CallICBase::Clear(Address address, Code* target) { | 489 void CallICBase::Clear(Address address, Code* target) { |
501 if (IsCleared(target)) return; | 490 if (IsCleared(target)) return; |
502 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); | 491 ContextualMode mode = IC::GetContextualMode(target->extra_ic_state()); |
503 Code* code = | 492 Code* code = target->GetIsolate()->stub_cache()->FindCallInitialize( |
504 target->GetIsolate()->stub_cache()->FindCallInitialize( | 493 target->arguments_count(), mode, target->kind()); |
505 target->arguments_count(), | |
506 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, | |
507 target->kind()); | |
508 SetTargetAtAddress(address, code); | 494 SetTargetAtAddress(address, code); |
509 } | 495 } |
510 | 496 |
511 | 497 |
512 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { | 498 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
513 if (IsCleared(target)) return; | 499 if (IsCleared(target)) return; |
514 // Make sure to also clear the map used in inline fast cases. If we | 500 // Make sure to also clear the map used in inline fast cases. If we |
515 // do not clear these maps, cached code can keep objects alive | 501 // do not clear these maps, cached code can keep objects alive |
516 // through the embedded maps. | 502 // through the embedded maps. |
517 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); | 503 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); |
518 } | 504 } |
519 | 505 |
520 | 506 |
521 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { | 507 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
522 if (IsCleared(target)) return; | 508 if (IsCleared(target)) return; |
523 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); | 509 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
| 510 Code::LOAD_IC, target->extra_ic_state()); |
| 511 SetTargetAtAddress(address, code); |
524 } | 512 } |
525 | 513 |
526 | 514 |
527 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 515 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
528 if (IsCleared(target)) return; | 516 if (IsCleared(target)) return; |
529 SetTargetAtAddress(address, | 517 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
530 *pre_monomorphic_stub( | 518 Code::STORE_IC, target->extra_ic_state()); |
531 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); | 519 SetTargetAtAddress(address, code); |
532 } | 520 } |
533 | 521 |
534 | 522 |
535 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 523 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
536 if (IsCleared(target)) return; | 524 if (IsCleared(target)) return; |
537 SetTargetAtAddress(address, | 525 SetTargetAtAddress(address, |
538 *pre_monomorphic_stub( | 526 *pre_monomorphic_stub( |
539 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); | 527 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); |
540 } | 528 } |
541 | 529 |
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1105 break; | 1093 break; |
1106 case DEBUG_STUB: | 1094 case DEBUG_STUB: |
1107 break; | 1095 break; |
1108 case GENERIC: | 1096 case GENERIC: |
1109 UNREACHABLE(); | 1097 UNREACHABLE(); |
1110 break; | 1098 break; |
1111 } | 1099 } |
1112 } | 1100 } |
1113 | 1101 |
1114 | 1102 |
| 1103 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { |
| 1104 Handle<Code> ic = isolate->stub_cache()->ComputeLoad( |
| 1105 UNINITIALIZED, IC::ComputeExtraICState(mode)); |
| 1106 return ic; |
| 1107 } |
| 1108 |
| 1109 |
| 1110 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, |
| 1111 ContextualMode mode) { |
| 1112 return isolate->stub_cache()->ComputeLoad( |
| 1113 PREMONOMORPHIC, IC::ComputeExtraICState(mode)); |
| 1114 } |
| 1115 |
| 1116 |
| 1117 Handle<Code> LoadIC::megamorphic_stub() { |
| 1118 return isolate()->stub_cache()->ComputeLoad( |
| 1119 MEGAMORPHIC, extra_ic_state()); |
| 1120 } |
| 1121 |
| 1122 |
1115 Handle<Code> LoadIC::SimpleFieldLoad(int offset, | 1123 Handle<Code> LoadIC::SimpleFieldLoad(int offset, |
1116 bool inobject, | 1124 bool inobject, |
1117 Representation representation) { | 1125 Representation representation) { |
1118 if (kind() == Code::LOAD_IC) { | 1126 if (kind() == Code::LOAD_IC) { |
1119 LoadFieldStub stub(inobject, offset, representation); | 1127 LoadFieldStub stub(inobject, offset, representation); |
1120 return stub.GetCode(isolate()); | 1128 return stub.GetCode(isolate()); |
1121 } else { | 1129 } else { |
1122 KeyedLoadFieldStub stub(inobject, offset, representation); | 1130 KeyedLoadFieldStub stub(inobject, offset, representation); |
1123 return stub.GetCode(isolate()); | 1131 return stub.GetCode(isolate()); |
1124 } | 1132 } |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1582 } | 1590 } |
1583 | 1591 |
1584 // Set the property. | 1592 // Set the property. |
1585 Handle<Object> result = JSReceiver::SetProperty( | 1593 Handle<Object> result = JSReceiver::SetProperty( |
1586 receiver, name, value, NONE, strict_mode(), store_mode); | 1594 receiver, name, value, NONE, strict_mode(), store_mode); |
1587 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1595 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
1588 return *result; | 1596 return *result; |
1589 } | 1597 } |
1590 | 1598 |
1591 | 1599 |
| 1600 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, |
| 1601 StrictModeFlag strict_mode, |
| 1602 ContextualMode mode) { |
| 1603 ExtraICState extra_state = ComputeExtraICState(strict_mode, mode); |
| 1604 Handle<Code> ic = isolate->stub_cache()->ComputeStore( |
| 1605 UNINITIALIZED, extra_state); |
| 1606 return ic; |
| 1607 } |
| 1608 |
| 1609 |
| 1610 Handle<Code> StoreIC::megamorphic_stub() { |
| 1611 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); |
| 1612 } |
| 1613 |
| 1614 |
| 1615 Handle<Code> StoreIC::generic_stub() const { |
| 1616 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); |
| 1617 } |
| 1618 |
| 1619 |
| 1620 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, |
| 1621 StrictModeFlag strict_mode, |
| 1622 ContextualMode contextual_mode) { |
| 1623 ExtraICState state = StoreIC::ComputeExtraICState(strict_mode, |
| 1624 contextual_mode); |
| 1625 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); |
| 1626 } |
| 1627 |
| 1628 |
1592 void StoreIC::UpdateCaches(LookupResult* lookup, | 1629 void StoreIC::UpdateCaches(LookupResult* lookup, |
1593 Handle<JSObject> receiver, | 1630 Handle<JSObject> receiver, |
1594 Handle<String> name, | 1631 Handle<String> name, |
1595 Handle<Object> value) { | 1632 Handle<Object> value) { |
1596 ASSERT(lookup->IsFound()); | 1633 ASSERT(lookup->IsFound()); |
1597 | 1634 |
1598 // These are not cacheable, so we never see such LookupResults here. | 1635 // These are not cacheable, so we never see such LookupResults here. |
1599 ASSERT(!lookup->IsHandler()); | 1636 ASSERT(!lookup->IsHandler()); |
1600 | 1637 |
1601 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); | 1638 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); |
(...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3138 #undef ADDR | 3175 #undef ADDR |
3139 }; | 3176 }; |
3140 | 3177 |
3141 | 3178 |
3142 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3179 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3143 return IC_utilities[id]; | 3180 return IC_utilities[id]; |
3144 } | 3181 } |
3145 | 3182 |
3146 | 3183 |
3147 } } // namespace v8::internal | 3184 } } // namespace v8::internal |
OLD | NEW |