Chromium Code Reviews| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 // Clearing these is tricky and does not | 486 // Clearing these is tricky and does not |
| 498 // make any performance difference. | 487 // make any performance difference. |
| 499 return; | 488 return; |
| 500 default: UNREACHABLE(); | 489 default: UNREACHABLE(); |
| 501 } | 490 } |
| 502 } | 491 } |
| 503 | 492 |
| 504 | 493 |
| 505 void CallICBase::Clear(Address address, Code* target) { | 494 void CallICBase::Clear(Address address, Code* target) { |
| 506 if (IsCleared(target)) return; | 495 if (IsCleared(target)) return; |
| 507 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); | 496 // Is the site contextual or not? |
|
Toon Verwaest
2013/12/04 18:10:52
That comment is a bit superfluous.
mvstanton
2013/12/04 22:08:10
Done.
| |
| 497 ContextualMode mode = IC::GetContextualMode(target->extra_ic_state()); | |
| 508 Code* code = | 498 Code* code = |
| 509 target->GetIsolate()->stub_cache()->FindCallInitialize( | 499 target->GetIsolate()->stub_cache()->FindCallInitialize( |
| 510 target->arguments_count(), | 500 target->arguments_count(), |
|
Toon Verwaest
2013/12/04 18:10:52
nit: I think you can join these 3 lines on 1 line.
mvstanton
2013/12/04 22:08:10
Done.
| |
| 511 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, | 501 mode, |
| 512 target->kind()); | 502 target->kind()); |
| 513 SetTargetAtAddress(address, code); | 503 SetTargetAtAddress(address, code); |
| 514 } | 504 } |
| 515 | 505 |
| 516 | 506 |
| 517 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { | 507 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 518 if (IsCleared(target)) return; | 508 if (IsCleared(target)) return; |
| 519 // Make sure to also clear the map used in inline fast cases. If we | 509 // Make sure to also clear the map used in inline fast cases. If we |
| 520 // do not clear these maps, cached code can keep objects alive | 510 // do not clear these maps, cached code can keep objects alive |
| 521 // through the embedded maps. | 511 // through the embedded maps. |
| 522 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); | 512 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); |
| 523 } | 513 } |
| 524 | 514 |
| 525 | 515 |
| 526 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { | 516 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 527 if (IsCleared(target)) return; | 517 if (IsCleared(target)) return; |
| 528 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); | 518 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
|
Toon Verwaest
2013/12/04 18:10:52
LoadIC::pre_monomorphic_stub(target->GetIsolate(),
mvstanton
2013/12/04 22:08:10
I can't quite do that here, because I can't create
| |
| 519 Code::LOAD_IC, | |
|
Toon Verwaest
2013/12/04 18:10:52
Join lines.
mvstanton
2013/12/04 22:08:10
Done.
| |
| 520 target->extra_ic_state()); | |
| 521 SetTargetAtAddress(address, code); | |
| 529 } | 522 } |
| 530 | 523 |
| 531 | 524 |
| 532 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 525 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 533 if (IsCleared(target)) return; | 526 if (IsCleared(target)) return; |
| 534 SetTargetAtAddress(address, | 527 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC( |
| 535 *pre_monomorphic_stub( | 528 Code::STORE_IC, |
|
Toon Verwaest
2013/12/04 18:10:52
Join lines.
mvstanton
2013/12/04 22:08:10
Done.
| |
| 536 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); | 529 target->extra_ic_state()); |
| 530 SetTargetAtAddress(address, code); | |
| 537 } | 531 } |
| 538 | 532 |
| 539 | 533 |
| 540 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { | 534 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { |
| 541 if (IsCleared(target)) return; | 535 if (IsCleared(target)) return; |
| 542 SetTargetAtAddress(address, | 536 SetTargetAtAddress(address, |
| 543 *pre_monomorphic_stub( | 537 *pre_monomorphic_stub( |
| 544 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); | 538 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); |
| 545 } | 539 } |
| 546 | 540 |
| (...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1110 break; | 1104 break; |
| 1111 case DEBUG_STUB: | 1105 case DEBUG_STUB: |
| 1112 break; | 1106 break; |
| 1113 case GENERIC: | 1107 case GENERIC: |
| 1114 UNREACHABLE(); | 1108 UNREACHABLE(); |
| 1115 break; | 1109 break; |
| 1116 } | 1110 } |
| 1117 } | 1111 } |
| 1118 | 1112 |
| 1119 | 1113 |
| 1114 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) { | |
| 1115 Handle<Code> ic = isolate->stub_cache()->ComputeLoad(UNINITIALIZED, | |
|
Toon Verwaest
2013/12/04 18:10:52
UNINITIALIZED on the next line, join with the mode
mvstanton
2013/12/04 22:08:10
Done, and in the two functions below too.
| |
| 1116 IC::ComputeExtraICState(mode)); | |
| 1117 return ic; | |
| 1118 } | |
| 1119 | |
| 1120 | |
| 1121 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, | |
| 1122 ContextualMode mode) { | |
| 1123 return isolate->stub_cache()->ComputeLoad(PREMONOMORPHIC, | |
| 1124 IC::ComputeExtraICState(mode)); | |
| 1125 } | |
| 1126 | |
| 1127 | |
| 1128 Handle<Code> LoadIC::megamorphic_stub() { | |
| 1129 return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, | |
| 1130 extra_ic_state()); | |
| 1131 } | |
| 1132 | |
| 1133 | |
| 1120 Handle<Code> LoadIC::SimpleFieldLoad(int offset, | 1134 Handle<Code> LoadIC::SimpleFieldLoad(int offset, |
| 1121 bool inobject, | 1135 bool inobject, |
| 1122 Representation representation) { | 1136 Representation representation) { |
| 1123 if (kind() == Code::LOAD_IC) { | 1137 if (kind() == Code::LOAD_IC) { |
| 1124 LoadFieldStub stub(inobject, offset, representation); | 1138 LoadFieldStub stub(inobject, offset, representation); |
| 1125 return stub.GetCode(isolate()); | 1139 return stub.GetCode(isolate()); |
| 1126 } else { | 1140 } else { |
| 1127 KeyedLoadFieldStub stub(inobject, offset, representation); | 1141 KeyedLoadFieldStub stub(inobject, offset, representation); |
| 1128 return stub.GetCode(isolate()); | 1142 return stub.GetCode(isolate()); |
| 1129 } | 1143 } |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1587 } | 1601 } |
| 1588 | 1602 |
| 1589 // Set the property. | 1603 // Set the property. |
| 1590 Handle<Object> result = JSReceiver::SetProperty( | 1604 Handle<Object> result = JSReceiver::SetProperty( |
| 1591 receiver, name, value, NONE, strict_mode(), store_mode); | 1605 receiver, name, value, NONE, strict_mode(), store_mode); |
| 1592 RETURN_IF_EMPTY_HANDLE(isolate(), result); | 1606 RETURN_IF_EMPTY_HANDLE(isolate(), result); |
| 1593 return *result; | 1607 return *result; |
| 1594 } | 1608 } |
| 1595 | 1609 |
| 1596 | 1610 |
| 1611 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, | |
| 1612 StrictModeFlag strict_mode, | |
| 1613 ContextualMode mode) { | |
| 1614 ExtraICState extra_state = ComputeExtraICState(strict_mode, mode); | |
| 1615 Handle<Code> ic = isolate->stub_cache()->ComputeStore(UNINITIALIZED, | |
| 1616 extra_state); | |
| 1617 return ic; | |
| 1618 } | |
| 1619 | |
| 1620 | |
| 1621 Handle<Code> StoreIC::megamorphic_stub() { | |
| 1622 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state()); | |
| 1623 } | |
| 1624 | |
| 1625 | |
| 1626 Handle<Code> StoreIC::generic_stub() const { | |
| 1627 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state()); | |
| 1628 } | |
| 1629 | |
| 1630 | |
| 1631 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, | |
| 1632 StrictModeFlag strict_mode, | |
| 1633 ContextualMode contextual_mode) { | |
| 1634 ExtraICState state = StoreIC::ComputeExtraICState(strict_mode, | |
| 1635 contextual_mode); | |
| 1636 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state); | |
| 1637 } | |
| 1638 | |
| 1639 | |
| 1597 void StoreIC::UpdateCaches(LookupResult* lookup, | 1640 void StoreIC::UpdateCaches(LookupResult* lookup, |
| 1598 Handle<JSObject> receiver, | 1641 Handle<JSObject> receiver, |
| 1599 Handle<String> name, | 1642 Handle<String> name, |
| 1600 Handle<Object> value) { | 1643 Handle<Object> value) { |
| 1601 ASSERT(lookup->IsFound()); | 1644 ASSERT(lookup->IsFound()); |
| 1602 | 1645 |
| 1603 // These are not cacheable, so we never see such LookupResults here. | 1646 // These are not cacheable, so we never see such LookupResults here. |
| 1604 ASSERT(!lookup->IsHandler()); | 1647 ASSERT(!lookup->IsHandler()); |
| 1605 | 1648 |
| 1606 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); | 1649 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); |
| (...skipping 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3143 #undef ADDR | 3186 #undef ADDR |
| 3144 }; | 3187 }; |
| 3145 | 3188 |
| 3146 | 3189 |
| 3147 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3190 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3148 return IC_utilities[id]; | 3191 return IC_utilities[id]; |
| 3149 } | 3192 } |
| 3150 | 3193 |
| 3151 | 3194 |
| 3152 } } // namespace v8::internal | 3195 } } // namespace v8::internal |
| OLD | NEW |