| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 84e65ace6d7d640c528ee30dff1995b104eb86f9..43d162c84ae8ea593debafc9851844fff6a54fc5 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -403,7 +403,7 @@ void IC::Clear(Isolate* isolate, Address address) {
|
|
|
|
|
| void CallICBase::Clear(Address address, Code* target) {
|
| - if (target->ic_state() == UNINITIALIZED) return;
|
| + if (IsCleared(target)) return;
|
| bool contextual = CallICBase::Contextual::decode(target->extra_ic_state());
|
| Code* code =
|
| target->GetIsolate()->stub_cache()->FindCallInitialize(
|
| @@ -415,35 +415,35 @@ void CallICBase::Clear(Address address, Code* target) {
|
|
|
|
|
| void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) {
|
| - if (target->ic_state() == UNINITIALIZED) return;
|
| + if (IsCleared(target)) return;
|
| // Make sure to also clear the map used in inline fast cases. If we
|
| // do not clear these maps, cached code can keep objects alive
|
| // through the embedded maps.
|
| - SetTargetAtAddress(address, *initialize_stub(isolate));
|
| + SetTargetAtAddress(address, *pre_monomorphic_stub(isolate));
|
| }
|
|
|
|
|
| void LoadIC::Clear(Isolate* isolate, Address address, Code* target) {
|
| - if (target->ic_state() == UNINITIALIZED) return;
|
| - SetTargetAtAddress(address, *initialize_stub(isolate));
|
| + if (IsCleared(target)) return;
|
| + SetTargetAtAddress(address, *pre_monomorphic_stub(isolate));
|
| }
|
|
|
|
|
| void StoreIC::Clear(Isolate* isolate, Address address, Code* target) {
|
| - if (target->ic_state() == UNINITIALIZED) return;
|
| + if (IsCleared(target)) return;
|
| SetTargetAtAddress(address,
|
| (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
| - ? *initialize_stub_strict(isolate)
|
| - : *initialize_stub(isolate));
|
| + ? *pre_monomorphic_stub_strict(isolate)
|
| + : *pre_monomorphic_stub(isolate));
|
| }
|
|
|
|
|
| void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) {
|
| - if (target->ic_state() == UNINITIALIZED) return;
|
| + if (IsCleared(target)) return;
|
| SetTargetAtAddress(address,
|
| (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
| - ? *initialize_stub_strict(isolate)
|
| - : *initialize_stub(isolate));
|
| + ? *pre_monomorphic_stub_strict(isolate)
|
| + : *pre_monomorphic_stub(isolate));
|
| }
|
|
|
|
|
| @@ -1348,20 +1348,19 @@ Handle<Code> LoadIC::ComputeLoadHandler(LookupResult* lookup,
|
| if (!holder.is_identical_to(receiver)) break;
|
| return isolate()->stub_cache()->ComputeLoadNormal(name, receiver);
|
| case CALLBACKS: {
|
| - Handle<Object> callback(lookup->GetCallbackObject(), isolate());
|
| - if (name->Equals(isolate()->heap()->length_string())) {
|
| - if (receiver->IsJSArray()) {
|
| - PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
|
| - JSArray::kLengthOffset / kPointerSize);
|
| - return isolate()->stub_cache()->ComputeLoadField(
|
| - name, receiver, receiver, lengthIndex, Representation::Tagged());
|
| - } else if (receiver->IsJSTypedArray()) {
|
| - PropertyIndex lengthIndex = PropertyIndex::NewHeaderIndex(
|
| - JSTypedArray::kLengthOffset / kPointerSize);
|
| + {
|
| + // Use simple field loads for some well-known callback properties.
|
| + int object_offset;
|
| + Handle<Map> map(receiver->map());
|
| + if (Accessors::IsJSObjectFieldAccessor(map, name, &object_offset)) {
|
| + PropertyIndex index =
|
| + PropertyIndex::NewHeaderIndex(object_offset / kPointerSize);
|
| return isolate()->stub_cache()->ComputeLoadField(
|
| - name, receiver, receiver, lengthIndex, Representation::Tagged());
|
| + name, receiver, receiver, index, Representation::Tagged());
|
| }
|
| }
|
| +
|
| + Handle<Object> callback(lookup->GetCallbackObject(), isolate());
|
| if (callback->IsExecutableAccessorInfo()) {
|
| Handle<ExecutableAccessorInfo> info =
|
| Handle<ExecutableAccessorInfo>::cast(callback);
|
|
|