| Index: src/ic.cc
|
| ===================================================================
|
| --- src/ic.cc (revision 5696)
|
| +++ src/ic.cc (working copy)
|
| @@ -476,9 +476,9 @@
|
| }
|
|
|
|
|
| -Object* CallICBase::LoadFunction(State state,
|
| - Handle<Object> object,
|
| - Handle<String> name) {
|
| +MaybeObject* CallICBase::LoadFunction(State state,
|
| + Handle<Object> object,
|
| + Handle<String> name) {
|
| // If the object is undefined or null it's illegal to try to get any
|
| // of its properties; throw a TypeError in that case.
|
| if (object->IsUndefined() || object->IsNull()) {
|
| @@ -493,7 +493,11 @@
|
| // the element if so.
|
| uint32_t index;
|
| if (name->AsArrayIndex(&index)) {
|
| - Object* result = object->GetElement(index);
|
| + Object* result;
|
| + { MaybeObject* maybe_result = object->GetElement(index);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| +
|
| if (result->IsJSFunction()) return result;
|
|
|
| // Try to find a suitable function delegate for the object at hand.
|
| @@ -523,8 +527,11 @@
|
|
|
| // Get the property.
|
| PropertyAttributes attr;
|
| - Object* result = object->GetProperty(*object, &lookup, *name, &attr);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + object->GetProperty(*object, &lookup, *name, &attr);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| if (lookup.type() == INTERCEPTOR) {
|
| // If the object does not have the requested property, check which
|
| // exception we need to throw.
|
| @@ -556,8 +563,11 @@
|
|
|
| // Try to find a suitable function delegate for the object at hand.
|
| result = TryCallAsFunction(result);
|
| - return result->IsJSFunction() ?
|
| - result : TypeError("property_not_function", object, name);
|
| + MaybeObject* answer = result;
|
| + if (!result->IsJSFunction()) {
|
| + answer = TypeError("property_not_function", object, name);
|
| + }
|
| + return answer;
|
| }
|
|
|
|
|
| @@ -578,27 +588,27 @@
|
| // Compute the number of arguments.
|
| int argc = target()->arguments_count();
|
| InLoopFlag in_loop = target()->ic_in_loop();
|
| - Object* code = NULL;
|
| -
|
| + MaybeObject* maybe_code = NULL;
|
| + Object* code;
|
| if (state == UNINITIALIZED) {
|
| // This is the first time we execute this inline cache.
|
| // Set the target to the pre monomorphic stub to delay
|
| // setting the monomorphic state.
|
| - code = StubCache::ComputeCallPreMonomorphic(argc, in_loop, kind_);
|
| + maybe_code = StubCache::ComputeCallPreMonomorphic(argc, in_loop, kind_);
|
| } else if (state == MONOMORPHIC) {
|
| - code = StubCache::ComputeCallMegamorphic(argc, in_loop, kind_);
|
| + maybe_code = StubCache::ComputeCallMegamorphic(argc, in_loop, kind_);
|
| } else {
|
| // Compute monomorphic stub.
|
| switch (lookup->type()) {
|
| case FIELD: {
|
| int index = lookup->GetFieldIndex();
|
| - code = StubCache::ComputeCallField(argc,
|
| - in_loop,
|
| - kind_,
|
| - *name,
|
| - *object,
|
| - lookup->holder(),
|
| - index);
|
| + maybe_code = StubCache::ComputeCallField(argc,
|
| + in_loop,
|
| + kind_,
|
| + *name,
|
| + *object,
|
| + lookup->holder(),
|
| + index);
|
| break;
|
| }
|
| case CONSTANT_FUNCTION: {
|
| @@ -606,13 +616,13 @@
|
| // call; used for rewriting to monomorphic state and making sure
|
| // that the code stub is in the stub cache.
|
| JSFunction* function = lookup->GetConstantFunction();
|
| - code = StubCache::ComputeCallConstant(argc,
|
| - in_loop,
|
| - kind_,
|
| - *name,
|
| - *object,
|
| - lookup->holder(),
|
| - function);
|
| + maybe_code = StubCache::ComputeCallConstant(argc,
|
| + in_loop,
|
| + kind_,
|
| + *name,
|
| + *object,
|
| + lookup->holder(),
|
| + function);
|
| break;
|
| }
|
| case NORMAL: {
|
| @@ -625,35 +635,35 @@
|
| JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
|
| if (!cell->value()->IsJSFunction()) return;
|
| JSFunction* function = JSFunction::cast(cell->value());
|
| - code = StubCache::ComputeCallGlobal(argc,
|
| - in_loop,
|
| - kind_,
|
| - *name,
|
| - *receiver,
|
| - global,
|
| - cell,
|
| - function);
|
| + maybe_code = StubCache::ComputeCallGlobal(argc,
|
| + in_loop,
|
| + kind_,
|
| + *name,
|
| + *receiver,
|
| + global,
|
| + cell,
|
| + function);
|
| } else {
|
| // There is only one shared stub for calling normalized
|
| // properties. It does not traverse the prototype chain, so the
|
| // property must be found in the receiver for the stub to be
|
| // applicable.
|
| if (lookup->holder() != *receiver) return;
|
| - code = StubCache::ComputeCallNormal(argc,
|
| - in_loop,
|
| - kind_,
|
| - *name,
|
| - *receiver);
|
| + maybe_code = StubCache::ComputeCallNormal(argc,
|
| + in_loop,
|
| + kind_,
|
| + *name,
|
| + *receiver);
|
| }
|
| break;
|
| }
|
| case INTERCEPTOR: {
|
| ASSERT(HasInterceptorGetter(lookup->holder()));
|
| - code = StubCache::ComputeCallInterceptor(argc,
|
| - kind_,
|
| - *name,
|
| - *object,
|
| - lookup->holder());
|
| + maybe_code = StubCache::ComputeCallInterceptor(argc,
|
| + kind_,
|
| + *name,
|
| + *object,
|
| + lookup->holder());
|
| break;
|
| }
|
| default:
|
| @@ -663,7 +673,7 @@
|
|
|
| // If we're unable to compute the stub (not enough memory left), we
|
| // simply avoid updating the caches.
|
| - if (code == NULL || code->IsFailure()) return;
|
| + if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
|
|
|
| // Patch the call site depending on the state of the cache.
|
| if (state == UNINITIALIZED ||
|
| @@ -688,9 +698,9 @@
|
| }
|
|
|
|
|
| -Object* KeyedCallIC::LoadFunction(State state,
|
| - Handle<Object> object,
|
| - Handle<Object> key) {
|
| +MaybeObject* KeyedCallIC::LoadFunction(State state,
|
| + Handle<Object> object,
|
| + Handle<Object> key) {
|
| if (key->IsSymbol()) {
|
| return CallICBase::LoadFunction(state, object, Handle<String>::cast(key));
|
| }
|
| @@ -706,9 +716,10 @@
|
| if (FLAG_use_ic && state != MEGAMORPHIC && !object->IsAccessCheckNeeded()) {
|
| int argc = target()->arguments_count();
|
| InLoopFlag in_loop = target()->ic_in_loop();
|
| - Object* code = StubCache::ComputeCallMegamorphic(
|
| + MaybeObject* maybe_code = StubCache::ComputeCallMegamorphic(
|
| argc, in_loop, Code::KEYED_CALL_IC);
|
| - if (!code->IsFailure()) {
|
| + Object* code;
|
| + if (maybe_code->ToObject(&code)) {
|
| set_target(Code::cast(code));
|
| #ifdef DEBUG
|
| TraceIC(
|
| @@ -716,11 +727,17 @@
|
| #endif
|
| }
|
| }
|
| - Object* result = Runtime::GetObjectProperty(object, key);
|
| + Object* result;
|
| + { MaybeObject* maybe_result = Runtime::GetObjectProperty(object, key);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| if (result->IsJSFunction()) return result;
|
| result = TryCallAsFunction(result);
|
| - return result->IsJSFunction() ?
|
| - result : TypeError("property_not_function", object, key);
|
| + MaybeObject* answer = result;
|
| + if (!result->IsJSFunction()) {
|
| + answer = TypeError("property_not_function", object, key);
|
| + }
|
| + return answer;
|
| }
|
|
|
|
|
| @@ -732,7 +749,9 @@
|
| #endif
|
|
|
|
|
| -Object* LoadIC::Load(State state, Handle<Object> object, Handle<String> name) {
|
| +MaybeObject* LoadIC::Load(State state,
|
| + Handle<Object> object,
|
| + Handle<String> name) {
|
| // If the object is undefined or null it's illegal to try to get any
|
| // of its properties; throw a TypeError in that case.
|
| if (object->IsUndefined() || object->IsNull()) {
|
| @@ -874,8 +893,11 @@
|
| PropertyAttributes attr;
|
| if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
|
| // Get the property.
|
| - Object* result = object->GetProperty(*object, &lookup, *name, &attr);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + object->GetProperty(*object, &lookup, *name, &attr);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| // If the property is not present, check if we need to throw an
|
| // exception.
|
| if (attr == ABSENT && IsContextual(object)) {
|
| @@ -904,28 +926,29 @@
|
| if (HasNormalObjectsInPrototypeChain(lookup, *object)) return;
|
|
|
| // Compute the code stub for this load.
|
| - Object* code = NULL;
|
| + MaybeObject* maybe_code = NULL;
|
| + Object* code;
|
| if (state == UNINITIALIZED) {
|
| // This is the first time we execute this inline cache.
|
| // Set the target to the pre monomorphic stub to delay
|
| // setting the monomorphic state.
|
| - code = pre_monomorphic_stub();
|
| + maybe_code = pre_monomorphic_stub();
|
| } else if (!lookup->IsProperty()) {
|
| // Nonexistent property. The result is undefined.
|
| - code = StubCache::ComputeLoadNonexistent(*name, *receiver);
|
| + maybe_code = StubCache::ComputeLoadNonexistent(*name, *receiver);
|
| } else {
|
| // Compute monomorphic stub.
|
| switch (lookup->type()) {
|
| case FIELD: {
|
| - code = StubCache::ComputeLoadField(*name, *receiver,
|
| - lookup->holder(),
|
| - lookup->GetFieldIndex());
|
| + maybe_code = StubCache::ComputeLoadField(*name, *receiver,
|
| + lookup->holder(),
|
| + lookup->GetFieldIndex());
|
| break;
|
| }
|
| case CONSTANT_FUNCTION: {
|
| Object* constant = lookup->GetConstantFunction();
|
| - code = StubCache::ComputeLoadConstant(*name, *receiver,
|
| - lookup->holder(), constant);
|
| + maybe_code = StubCache::ComputeLoadConstant(*name, *receiver,
|
| + lookup->holder(), constant);
|
| break;
|
| }
|
| case NORMAL: {
|
| @@ -933,18 +956,18 @@
|
| GlobalObject* global = GlobalObject::cast(lookup->holder());
|
| JSGlobalPropertyCell* cell =
|
| JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
|
| - code = StubCache::ComputeLoadGlobal(*name,
|
| - *receiver,
|
| - global,
|
| - cell,
|
| - lookup->IsDontDelete());
|
| + maybe_code = StubCache::ComputeLoadGlobal(*name,
|
| + *receiver,
|
| + global,
|
| + cell,
|
| + lookup->IsDontDelete());
|
| } else {
|
| // There is only one shared stub for loading normalized
|
| // properties. It does not traverse the prototype chain, so the
|
| // property must be found in the receiver for the stub to be
|
| // applicable.
|
| if (lookup->holder() != *receiver) return;
|
| - code = StubCache::ComputeLoadNormal();
|
| + maybe_code = StubCache::ComputeLoadNormal();
|
| }
|
| break;
|
| }
|
| @@ -953,14 +976,14 @@
|
| AccessorInfo* callback =
|
| AccessorInfo::cast(lookup->GetCallbackObject());
|
| if (v8::ToCData<Address>(callback->getter()) == 0) return;
|
| - code = StubCache::ComputeLoadCallback(*name, *receiver,
|
| - lookup->holder(), callback);
|
| + maybe_code = StubCache::ComputeLoadCallback(*name, *receiver,
|
| + lookup->holder(), callback);
|
| break;
|
| }
|
| case INTERCEPTOR: {
|
| ASSERT(HasInterceptorGetter(lookup->holder()));
|
| - code = StubCache::ComputeLoadInterceptor(*name, *receiver,
|
| - lookup->holder());
|
| + maybe_code = StubCache::ComputeLoadInterceptor(*name, *receiver,
|
| + lookup->holder());
|
| break;
|
| }
|
| default:
|
| @@ -970,7 +993,7 @@
|
|
|
| // If we're unable to compute the stub (not enough memory left), we
|
| // simply avoid updating the caches.
|
| - if (code == NULL || code->IsFailure()) return;
|
| + if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
|
|
|
| // Patch the call site depending on the state of the cache.
|
| if (state == UNINITIALIZED || state == PREMONOMORPHIC ||
|
| @@ -993,9 +1016,9 @@
|
| }
|
|
|
|
|
| -Object* KeyedLoadIC::Load(State state,
|
| - Handle<Object> object,
|
| - Handle<Object> key) {
|
| +MaybeObject* KeyedLoadIC::Load(State state,
|
| + Handle<Object> object,
|
| + Handle<Object> key) {
|
| if (key->IsSymbol()) {
|
| Handle<String> name = Handle<String>::cast(key);
|
|
|
| @@ -1010,8 +1033,10 @@
|
| if (object->IsString() && name->Equals(Heap::length_symbol())) {
|
| Handle<String> string = Handle<String>::cast(object);
|
| Object* code = NULL;
|
| - code = StubCache::ComputeKeyedLoadStringLength(*name, *string);
|
| - if (code->IsFailure()) return code;
|
| + { MaybeObject* maybe_code =
|
| + StubCache::ComputeKeyedLoadStringLength(*name, *string);
|
| + if (!maybe_code->ToObject(&code)) return maybe_code;
|
| + }
|
| set_target(Code::cast(code));
|
| #ifdef DEBUG
|
| TraceIC("KeyedLoadIC", name, state, target());
|
| @@ -1022,8 +1047,11 @@
|
| // Use specialized code for getting the length of arrays.
|
| if (object->IsJSArray() && name->Equals(Heap::length_symbol())) {
|
| Handle<JSArray> array = Handle<JSArray>::cast(object);
|
| - Object* code = StubCache::ComputeKeyedLoadArrayLength(*name, *array);
|
| - if (code->IsFailure()) return code;
|
| + Object* code;
|
| + { MaybeObject* maybe_code =
|
| + StubCache::ComputeKeyedLoadArrayLength(*name, *array);
|
| + if (!maybe_code->ToObject(&code)) return maybe_code;
|
| + }
|
| set_target(Code::cast(code));
|
| #ifdef DEBUG
|
| TraceIC("KeyedLoadIC", name, state, target());
|
| @@ -1035,9 +1063,11 @@
|
| if (object->IsJSFunction() && name->Equals(Heap::prototype_symbol()) &&
|
| JSFunction::cast(*object)->should_have_prototype()) {
|
| Handle<JSFunction> function = Handle<JSFunction>::cast(object);
|
| - Object* code =
|
| - StubCache::ComputeKeyedLoadFunctionPrototype(*name, *function);
|
| - if (code->IsFailure()) return code;
|
| + Object* code;
|
| + { MaybeObject* maybe_code =
|
| + StubCache::ComputeKeyedLoadFunctionPrototype(*name, *function);
|
| + if (!maybe_code->ToObject(&code)) return maybe_code;
|
| + }
|
| set_target(Code::cast(code));
|
| #ifdef DEBUG
|
| TraceIC("KeyedLoadIC", name, state, target());
|
| @@ -1074,8 +1104,11 @@
|
| PropertyAttributes attr;
|
| if (lookup.IsProperty() && lookup.type() == INTERCEPTOR) {
|
| // Get the property.
|
| - Object* result = object->GetProperty(*object, &lookup, *name, &attr);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + object->GetProperty(*object, &lookup, *name, &attr);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| // If the property is not present, check if we need to throw an
|
| // exception.
|
| if (attr == ABSENT && IsContextual(object)) {
|
| @@ -1133,26 +1166,29 @@
|
| if (HasNormalObjectsInPrototypeChain(lookup, *object)) return;
|
|
|
| // Compute the code stub for this load.
|
| - Object* code = NULL;
|
| + MaybeObject* maybe_code = NULL;
|
| + Object* code;
|
|
|
| if (state == UNINITIALIZED) {
|
| // This is the first time we execute this inline cache.
|
| // Set the target to the pre monomorphic stub to delay
|
| // setting the monomorphic state.
|
| - code = pre_monomorphic_stub();
|
| + maybe_code = pre_monomorphic_stub();
|
| } else {
|
| // Compute a monomorphic stub.
|
| switch (lookup->type()) {
|
| case FIELD: {
|
| - code = StubCache::ComputeKeyedLoadField(*name, *receiver,
|
| - lookup->holder(),
|
| - lookup->GetFieldIndex());
|
| + maybe_code = StubCache::ComputeKeyedLoadField(*name, *receiver,
|
| + lookup->holder(),
|
| + lookup->GetFieldIndex());
|
| break;
|
| }
|
| case CONSTANT_FUNCTION: {
|
| Object* constant = lookup->GetConstantFunction();
|
| - code = StubCache::ComputeKeyedLoadConstant(*name, *receiver,
|
| - lookup->holder(), constant);
|
| + maybe_code = StubCache::ComputeKeyedLoadConstant(*name,
|
| + *receiver,
|
| + lookup->holder(),
|
| + constant);
|
| break;
|
| }
|
| case CALLBACKS: {
|
| @@ -1160,20 +1196,22 @@
|
| AccessorInfo* callback =
|
| AccessorInfo::cast(lookup->GetCallbackObject());
|
| if (v8::ToCData<Address>(callback->getter()) == 0) return;
|
| - code = StubCache::ComputeKeyedLoadCallback(*name, *receiver,
|
| - lookup->holder(), callback);
|
| + maybe_code = StubCache::ComputeKeyedLoadCallback(*name,
|
| + *receiver,
|
| + lookup->holder(),
|
| + callback);
|
| break;
|
| }
|
| case INTERCEPTOR: {
|
| ASSERT(HasInterceptorGetter(lookup->holder()));
|
| - code = StubCache::ComputeKeyedLoadInterceptor(*name, *receiver,
|
| - lookup->holder());
|
| + maybe_code = StubCache::ComputeKeyedLoadInterceptor(*name, *receiver,
|
| + lookup->holder());
|
| break;
|
| }
|
| default: {
|
| // Always rewrite to the generic case so that we do not
|
| // repeatedly try to rewrite.
|
| - code = generic_stub();
|
| + maybe_code = generic_stub();
|
| break;
|
| }
|
| }
|
| @@ -1181,7 +1219,7 @@
|
|
|
| // If we're unable to compute the stub (not enough memory left), we
|
| // simply avoid updating the caches.
|
| - if (code == NULL || code->IsFailure()) return;
|
| + if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
|
|
|
| // Patch the call site depending on the state of the cache. Make
|
| // sure to always rewrite from monomorphic to megamorphic.
|
| @@ -1229,10 +1267,10 @@
|
| }
|
|
|
|
|
| -Object* StoreIC::Store(State state,
|
| - Handle<Object> object,
|
| - Handle<String> name,
|
| - Handle<Object> value) {
|
| +MaybeObject* StoreIC::Store(State state,
|
| + Handle<Object> object,
|
| + Handle<String> name,
|
| + Handle<Object> value) {
|
| // If the object is undefined or null it's illegal to try to set any
|
| // properties on it; throw a TypeError in that case.
|
| if (object->IsUndefined() || object->IsNull()) {
|
| @@ -1345,11 +1383,12 @@
|
| // Compute the code stub for this store; used for rewriting to
|
| // monomorphic state and making sure that the code stub is in the
|
| // stub cache.
|
| + MaybeObject* maybe_code = NULL;
|
| Object* code = NULL;
|
| switch (type) {
|
| case FIELD: {
|
| - code = StubCache::ComputeStoreField(*name, *receiver,
|
| - lookup->GetFieldIndex());
|
| + maybe_code = StubCache::ComputeStoreField(*name, *receiver,
|
| + lookup->GetFieldIndex());
|
| break;
|
| }
|
| case MAP_TRANSITION: {
|
| @@ -1358,7 +1397,8 @@
|
| ASSERT(type == MAP_TRANSITION);
|
| Handle<Map> transition(lookup->GetTransitionMap());
|
| int index = transition->PropertyIndexFor(*name);
|
| - code = StubCache::ComputeStoreField(*name, *receiver, index, *transition);
|
| + maybe_code = StubCache::ComputeStoreField(*name, *receiver,
|
| + index, *transition);
|
| break;
|
| }
|
| case NORMAL: {
|
| @@ -1369,10 +1409,10 @@
|
| Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
|
| JSGlobalPropertyCell* cell =
|
| JSGlobalPropertyCell::cast(global->GetPropertyCell(lookup));
|
| - code = StubCache::ComputeStoreGlobal(*name, *global, cell);
|
| + maybe_code = StubCache::ComputeStoreGlobal(*name, *global, cell);
|
| } else {
|
| if (lookup->holder() != *receiver) return;
|
| - code = StubCache::ComputeStoreNormal();
|
| + maybe_code = StubCache::ComputeStoreNormal();
|
| }
|
| break;
|
| }
|
| @@ -1380,12 +1420,12 @@
|
| if (!lookup->GetCallbackObject()->IsAccessorInfo()) return;
|
| AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject());
|
| if (v8::ToCData<Address>(callback->setter()) == 0) return;
|
| - code = StubCache::ComputeStoreCallback(*name, *receiver, callback);
|
| + maybe_code = StubCache::ComputeStoreCallback(*name, *receiver, callback);
|
| break;
|
| }
|
| case INTERCEPTOR: {
|
| ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
|
| - code = StubCache::ComputeStoreInterceptor(*name, *receiver);
|
| + maybe_code = StubCache::ComputeStoreInterceptor(*name, *receiver);
|
| break;
|
| }
|
| default:
|
| @@ -1394,7 +1434,7 @@
|
|
|
| // If we're unable to compute the stub (not enough memory left), we
|
| // simply avoid updating the caches.
|
| - if (code == NULL || code->IsFailure()) return;
|
| + if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
|
|
|
| // Patch the call site depending on the state of the cache.
|
| if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
|
| @@ -1413,10 +1453,10 @@
|
| }
|
|
|
|
|
| -Object* KeyedStoreIC::Store(State state,
|
| - Handle<Object> object,
|
| - Handle<Object> key,
|
| - Handle<Object> value) {
|
| +MaybeObject* KeyedStoreIC::Store(State state,
|
| + Handle<Object> object,
|
| + Handle<Object> key,
|
| + Handle<Object> value) {
|
| if (key->IsSymbol()) {
|
| Handle<String> name = Handle<String>::cast(key);
|
|
|
| @@ -1496,12 +1536,13 @@
|
| // Compute the code stub for this store; used for rewriting to
|
| // monomorphic state and making sure that the code stub is in the
|
| // stub cache.
|
| + MaybeObject* maybe_code = NULL;
|
| Object* code = NULL;
|
|
|
| switch (type) {
|
| case FIELD: {
|
| - code = StubCache::ComputeKeyedStoreField(*name, *receiver,
|
| - lookup->GetFieldIndex());
|
| + maybe_code = StubCache::ComputeKeyedStoreField(*name, *receiver,
|
| + lookup->GetFieldIndex());
|
| break;
|
| }
|
| case MAP_TRANSITION: {
|
| @@ -1510,8 +1551,8 @@
|
| ASSERT(type == MAP_TRANSITION);
|
| Handle<Map> transition(lookup->GetTransitionMap());
|
| int index = transition->PropertyIndexFor(*name);
|
| - code = StubCache::ComputeKeyedStoreField(*name, *receiver,
|
| - index, *transition);
|
| + maybe_code = StubCache::ComputeKeyedStoreField(*name, *receiver,
|
| + index, *transition);
|
| break;
|
| }
|
| // fall through.
|
| @@ -1519,14 +1560,14 @@
|
| default: {
|
| // Always rewrite to the generic case so that we do not
|
| // repeatedly try to rewrite.
|
| - code = generic_stub();
|
| + maybe_code = generic_stub();
|
| break;
|
| }
|
| }
|
|
|
| // If we're unable to compute the stub (not enough memory left), we
|
| // simply avoid updating the caches.
|
| - if (code == NULL || code->IsFailure()) return;
|
| + if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
|
|
|
| // Patch the call site depending on the state of the cache. Make
|
| // sure to always rewrite from monomorphic to megamorphic.
|
| @@ -1562,13 +1603,16 @@
|
|
|
|
|
| // Used from ic-<arch>.cc.
|
| -Object* CallIC_Miss(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* CallIC_Miss(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 2);
|
| CallIC ic;
|
| IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
| - Object* result =
|
| - ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
|
|
| // The first time the inline cache is updated may be the first time the
|
| // function it references gets called. If the function was lazily compiled
|
| @@ -1585,13 +1629,16 @@
|
|
|
|
|
| // Used from ic-<arch>.cc.
|
| -Object* KeyedCallIC_Miss(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* KeyedCallIC_Miss(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 2);
|
| KeyedCallIC ic;
|
| IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
| - Object* result =
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| ic.LoadFunction(state, args.at<Object>(0), args.at<Object>(1));
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
|
|
| if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
|
| return result;
|
| @@ -1601,7 +1648,7 @@
|
|
|
|
|
| // Used from ic-<arch>.cc.
|
| -Object* LoadIC_Miss(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* LoadIC_Miss(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 2);
|
| LoadIC ic;
|
| @@ -1611,7 +1658,7 @@
|
|
|
|
|
| // Used from ic-<arch>.cc
|
| -Object* KeyedLoadIC_Miss(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* KeyedLoadIC_Miss(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 2);
|
| KeyedLoadIC ic;
|
| @@ -1621,7 +1668,7 @@
|
|
|
|
|
| // Used from ic-<arch>.cc.
|
| -Object* StoreIC_Miss(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* StoreIC_Miss(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 3);
|
| StoreIC ic;
|
| @@ -1631,15 +1678,20 @@
|
| }
|
|
|
|
|
| -Object* StoreIC_ArrayLength(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* StoreIC_ArrayLength(Arguments args) {
|
| NoHandleAllocation nha;
|
|
|
| ASSERT(args.length() == 2);
|
| JSObject* receiver = JSObject::cast(args[0]);
|
| Object* len = args[1];
|
|
|
| - Object* result = receiver->SetElementsLength(len);
|
| - if (result->IsFailure()) return result;
|
| + // The generated code should filter out non-Smis before we get here.
|
| + ASSERT(len->IsSmi());
|
| +
|
| + Object* result;
|
| + { MaybeObject* maybe_result = receiver->SetElementsLength(len);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| return len;
|
| }
|
|
|
| @@ -1647,7 +1699,7 @@
|
| // Extend storage is called in a store inline cache when
|
| // it is necessary to extend the properties array of a
|
| // JSObject.
|
| -Object* SharedStoreIC_ExtendStorage(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* SharedStoreIC_ExtendStorage(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 3);
|
|
|
| @@ -1664,8 +1716,10 @@
|
| FixedArray* old_storage = object->properties();
|
| int new_unused = transition->unused_property_fields();
|
| int new_size = old_storage->length() + new_unused + 1;
|
| - Object* result = old_storage->CopySize(new_size);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = old_storage->CopySize(new_size);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| FixedArray* new_storage = FixedArray::cast(result);
|
| new_storage->set(old_storage->length(), value);
|
|
|
| @@ -1679,7 +1733,7 @@
|
|
|
|
|
| // Used from ic-<arch>.cc.
|
| -Object* KeyedStoreIC_Miss(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* KeyedStoreIC_Miss(Arguments args) {
|
| NoHandleAllocation na;
|
| ASSERT(args.length() == 3);
|
| KeyedStoreIC ic;
|
| @@ -1744,7 +1798,7 @@
|
| Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info);
|
|
|
|
|
| -Object* BinaryOp_Patch(Arguments args) {
|
| +MUST_USE_RESULT MaybeObject* BinaryOp_Patch(Arguments args) {
|
| ASSERT(args.length() == 5);
|
|
|
| Handle<Object> left = args.at<Object>(0);
|
|
|