Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value) {
- // Skip JSGlobalProxy.
ASSERT(!receiver->IsJSGlobalProxy());
-
ASSERT(StoreICableLookup(lookup));
+ // These are not cacheable, so we never see such LookupResults here.
+ ASSERT(lookup->type() != HANDLER);
+ // We get only called for properties or transitions, see StoreICableLookup.
+ ASSERT(lookup->type() != NULL_DESCRIPTOR);
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
break;
case MAP_TRANSITION: {
if (lookup->GetAttributes() != NONE) return;
- ASSERT(type == MAP_TRANSITION);
Handle<Map> transition(lookup->GetTransitionMap());
int index = transition->PropertyIndexFor(*name);
code = isolate()->stub_cache()->ComputeStoreField(
code = isolate()->stub_cache()->ComputeStoreInterceptor(
name, receiver, strict_mode);
break;
- default:
+ case CONSTANT_FUNCTION:
+ case CONSTANT_TRANSITION:
+ case ELEMENTS_TRANSITION:
+ return;
+ case HANDLER:
+ case NULL_DESCRIPTOR:
+ UNREACHABLE();
return;
}
return *value;
}
- // Lookup the property locally in the receiver.
- LookupResult lookup(isolate());
- receiver->LocalLookup(*name, &lookup);
-
// Update inline cache and stub cache.
- if (FLAG_use_ic) {
- UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
+ if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
+ LookupResult lookup(isolate());
+ if (LookupForWrite(receiver, name, &lookup)) {
+ UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
+ }
}
// Set the property.
Handle<JSObject> receiver,
Handle<String> name,
Handle<Object> value) {
- // Skip JSGlobalProxy.
- if (receiver->IsJSGlobalProxy()) return;
-
- // Bail out if we didn't find a result.
- if (!lookup->IsPropertyOrTransition() || !lookup->IsCacheable()) return;
-
- // If the property is read-only, we leave the IC in its current
- // state.
- if (lookup->IsReadOnly()) return;
+ ASSERT(!receiver->IsJSGlobalProxy());
+ ASSERT(StoreICableLookup(lookup));
+ // These are not cacheable, so we never see such LookupResults here.
+ ASSERT(lookup->type() != HANDLER);
+ // We get only called for properties or transitions, see StoreICableLookup.
+ ASSERT(lookup->type() != NULL_DESCRIPTOR);
// If the property has a non-field type allowing map transitions
// where there is extra room in the object, we leave the IC in its
break;
case MAP_TRANSITION:
if (lookup->GetAttributes() == NONE) {
- ASSERT(type == MAP_TRANSITION);
Handle<Map> transition(lookup->GetTransitionMap());
int index = transition->PropertyIndexFor(*name);
code = isolate()->stub_cache()->ComputeKeyedStoreField(
break;
}
// fall through.
- default:
+ case NORMAL:
+ case CONSTANT_FUNCTION:
+ case CALLBACKS:
+ case INTERCEPTOR:
+ case CONSTANT_TRANSITION:
+ case ELEMENTS_TRANSITION:
// Always rewrite to the generic case so that we do not
// repeatedly try to rewrite.
code = (strict_mode == kStrictMode)
? generic_stub_strict()
: generic_stub();
break;
+ case HANDLER:
+ case NULL_DESCRIPTOR:
+ UNREACHABLE();
+ return;
}
ASSERT(!code.is_null());
case NULL_DESCRIPTOR:
case ELEMENTS_TRANSITION:
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
- default:
+ case HANDLER:
UNREACHABLE();
+ return value;
}
- UNREACHABLE();
+ UNREACHABLE(); // keep the compiler happy
return value;
}
case NULL_DESCRIPTOR:
case ELEMENTS_TRANSITION:
return ConvertDescriptorToFieldAndMapTransition(name, value, attributes);
- default:
+ case HANDLER:
UNREACHABLE();
+ return value;
}
- UNREACHABLE();
+ UNREACHABLE(); // keep the compiler happy
return value;
}
case INTERCEPTOR:
case ELEMENTS_TRANSITION:
break;
- default:
+ case HANDLER:
+ case NORMAL:
UNREACHABLE();
+ break;
}
}
void Map::CreateBackPointers() {
DescriptorArray* descriptors = instance_descriptors();
for (int i = 0; i < descriptors->number_of_descriptors(); i++) {
- if (descriptors->GetType(i) == MAP_TRANSITION ||
- descriptors->GetType(i) == ELEMENTS_TRANSITION ||
- descriptors->GetType(i) == CONSTANT_TRANSITION) {
+ if (descriptors->IsTransition(i)) {
Object* object = reinterpret_cast<Object*>(descriptors->GetValue(i));
if (object->IsMap()) {
CreateOneBackPointer(reinterpret_cast<Map*>(object));
// map is not reached again by following a back pointer from a
// non-live object.
PropertyDetails details(Smi::cast(contents->get(i + 1)));
- if (details.type() == MAP_TRANSITION ||
- details.type() == ELEMENTS_TRANSITION ||
- details.type() == CONSTANT_TRANSITION) {
+ if (IsTransitionType(details.type())) {
Object* object = reinterpret_cast<Object*>(contents->get(i));
if (object->IsMap()) {
Map* target = reinterpret_cast<Map*>(object);
case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION";
case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR";
}
- UNREACHABLE();
+ UNREACHABLE(); // keep the compiler happy
return NULL;
}