| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index ac20b2e6f7842cc458243bca6e48dc09db8e2442..c1cb922de55bf831cad9deb8a5a83876d05b65ad 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -54,16 +54,18 @@ const int kGetterIndex = 0;
|
| const int kSetterIndex = 1;
|
|
|
|
|
| -MUST_USE_RESULT static Object* CreateJSValue(JSFunction* constructor,
|
| - Object* value) {
|
| - Object* result = Heap::AllocateJSObject(constructor);
|
| - if (result->IsFailure()) return result;
|
| +MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
|
| + Object* value) {
|
| + Object* result;
|
| + { MaybeObject* maybe_result = Heap::AllocateJSObject(constructor);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| JSValue::cast(result)->set_value(value);
|
| return result;
|
| }
|
|
|
|
|
| -Object* Object::ToObject(Context* global_context) {
|
| +MaybeObject* Object::ToObject(Context* global_context) {
|
| if (IsNumber()) {
|
| return CreateJSValue(global_context->number_function(), this);
|
| } else if (IsBoolean()) {
|
| @@ -76,7 +78,7 @@ Object* Object::ToObject(Context* global_context) {
|
| }
|
|
|
|
|
| -Object* Object::ToObject() {
|
| +MaybeObject* Object::ToObject() {
|
| Context* global_context = Top::context()->global_context();
|
| if (IsJSObject()) {
|
| return this;
|
| @@ -130,28 +132,28 @@ void Object::Lookup(String* name, LookupResult* result) {
|
| }
|
|
|
|
|
| -Object* Object::GetPropertyWithReceiver(Object* receiver,
|
| - String* name,
|
| - PropertyAttributes* attributes) {
|
| +MaybeObject* Object::GetPropertyWithReceiver(Object* receiver,
|
| + String* name,
|
| + PropertyAttributes* attributes) {
|
| LookupResult result;
|
| Lookup(name, &result);
|
| - Object* value = GetProperty(receiver, &result, name, attributes);
|
| + MaybeObject* value = GetProperty(receiver, &result, name, attributes);
|
| ASSERT(*attributes <= ABSENT);
|
| return value;
|
| }
|
|
|
|
|
| -Object* Object::GetPropertyWithCallback(Object* receiver,
|
| - Object* structure,
|
| - String* name,
|
| - Object* holder) {
|
| +MaybeObject* Object::GetPropertyWithCallback(Object* receiver,
|
| + Object* structure,
|
| + String* name,
|
| + Object* holder) {
|
| // To accommodate both the old and the new api we switch on the
|
| // data structure used to store the callbacks. Eventually proxy
|
| // callbacks should be phased out.
|
| if (structure->IsProxy()) {
|
| AccessorDescriptor* callback =
|
| reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());
|
| - Object* value = (callback->getter)(receiver, callback->data);
|
| + MaybeObject* value = (callback->getter)(receiver, callback->data);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| return value;
|
| }
|
| @@ -195,8 +197,8 @@ Object* Object::GetPropertyWithCallback(Object* receiver,
|
| }
|
|
|
|
|
| -Object* Object::GetPropertyWithDefinedGetter(Object* receiver,
|
| - JSFunction* getter) {
|
| +MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver,
|
| + JSFunction* getter) {
|
| HandleScope scope;
|
| Handle<JSFunction> fun(JSFunction::cast(getter));
|
| Handle<Object> self(receiver);
|
| @@ -216,7 +218,7 @@ Object* Object::GetPropertyWithDefinedGetter(Object* receiver,
|
|
|
|
|
| // Only deal with CALLBACKS and INTERCEPTOR
|
| -Object* JSObject::GetPropertyWithFailedAccessCheck(
|
| +MaybeObject* JSObject::GetPropertyWithFailedAccessCheck(
|
| Object* receiver,
|
| LookupResult* result,
|
| String* name,
|
| @@ -365,19 +367,26 @@ Object* JSObject::SetNormalizedProperty(LookupResult* result, Object* value) {
|
| }
|
|
|
|
|
| -Object* JSObject::SetNormalizedProperty(String* name,
|
| - Object* value,
|
| - PropertyDetails details) {
|
| +MaybeObject* JSObject::SetNormalizedProperty(String* name,
|
| + Object* value,
|
| + PropertyDetails details) {
|
| ASSERT(!HasFastProperties());
|
| int entry = property_dictionary()->FindEntry(name);
|
| if (entry == StringDictionary::kNotFound) {
|
| Object* store_value = value;
|
| if (IsGlobalObject()) {
|
| - store_value = Heap::AllocateJSGlobalPropertyCell(value);
|
| - if (store_value->IsFailure()) return store_value;
|
| + { MaybeObject* maybe_store_value =
|
| + Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (!maybe_store_value->ToObject(&store_value)) {
|
| + return maybe_store_value;
|
| + }
|
| + }
|
| + }
|
| + Object* dict;
|
| + { MaybeObject* maybe_dict =
|
| + property_dictionary()->Add(name, store_value, details);
|
| + if (!maybe_dict->ToObject(&dict)) return maybe_dict;
|
| }
|
| - Object* dict = property_dictionary()->Add(name, store_value, details);
|
| - if (dict->IsFailure()) return dict;
|
| set_properties(StringDictionary::cast(dict));
|
| return value;
|
| }
|
| @@ -398,7 +407,7 @@ Object* JSObject::SetNormalizedProperty(String* name,
|
| }
|
|
|
|
|
| -Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
|
| +MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
|
| ASSERT(!HasFastProperties());
|
| StringDictionary* dictionary = property_dictionary();
|
| int entry = dictionary->FindEntry(name);
|
| @@ -412,8 +421,10 @@ Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) {
|
| // map change to invalidate any ICs that think they can load
|
| // from the DontDelete cell without checking if it contains
|
| // the hole value.
|
| - Object* new_map = map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
| set_map(Map::cast(new_map));
|
| }
|
| JSGlobalPropertyCell* cell =
|
| @@ -443,10 +454,10 @@ bool JSObject::IsDirty() {
|
| }
|
|
|
|
|
| -Object* Object::GetProperty(Object* receiver,
|
| - LookupResult* result,
|
| - String* name,
|
| - PropertyAttributes* attributes) {
|
| +MaybeObject* Object::GetProperty(Object* receiver,
|
| + LookupResult* result,
|
| + String* name,
|
| + PropertyAttributes* attributes) {
|
| // Make sure that the top context does not change when doing
|
| // callbacks or interceptor calls.
|
| AssertNoContextChange ncc;
|
| @@ -512,7 +523,7 @@ Object* Object::GetProperty(Object* receiver,
|
| }
|
|
|
|
|
| -Object* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
|
| +MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) {
|
| // Non-JS objects do not have integer indexed properties.
|
| if (!IsJSObject()) return Heap::undefined_value();
|
| return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver),
|
| @@ -598,7 +609,7 @@ static bool AnWord(String* str) {
|
| }
|
|
|
|
|
| -Object* String::SlowTryFlatten(PretenureFlag pretenure) {
|
| +MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) {
|
| #ifdef DEBUG
|
| // Do not attempt to flatten in debug mode when allocation is not
|
| // allowed. This is to avoid an assertion failure when allocating.
|
| @@ -621,8 +632,9 @@ Object* String::SlowTryFlatten(PretenureFlag pretenure) {
|
| Object* object;
|
| String* result;
|
| if (IsAsciiRepresentation()) {
|
| - object = Heap::AllocateRawAsciiString(len, tenure);
|
| - if (object->IsFailure()) return object;
|
| + { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(len, tenure);
|
| + if (!maybe_object->ToObject(&object)) return maybe_object;
|
| + }
|
| result = String::cast(object);
|
| String* first = cs->first();
|
| int first_length = first->length();
|
| @@ -634,8 +646,10 @@ Object* String::SlowTryFlatten(PretenureFlag pretenure) {
|
| 0,
|
| len - first_length);
|
| } else {
|
| - object = Heap::AllocateRawTwoByteString(len, tenure);
|
| - if (object->IsFailure()) return object;
|
| + { MaybeObject* maybe_object =
|
| + Heap::AllocateRawTwoByteString(len, tenure);
|
| + if (!maybe_object->ToObject(&object)) return maybe_object;
|
| + }
|
| result = String::cast(object);
|
| uc16* dest = SeqTwoByteString::cast(result)->GetChars();
|
| String* first = cs->first();
|
| @@ -1169,16 +1183,18 @@ String* JSObject::constructor_name() {
|
| }
|
|
|
|
|
| -Object* JSObject::AddFastPropertyUsingMap(Map* new_map,
|
| - String* name,
|
| - Object* value) {
|
| +MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
|
| + String* name,
|
| + Object* value) {
|
| int index = new_map->PropertyIndexFor(name);
|
| if (map()->unused_property_fields() == 0) {
|
| ASSERT(map()->unused_property_fields() == 0);
|
| int new_unused = new_map->unused_property_fields();
|
| - Object* values =
|
| - properties()->CopySize(properties()->length() + new_unused + 1);
|
| - if (values->IsFailure()) return values;
|
| + Object* values;
|
| + { MaybeObject* maybe_values =
|
| + properties()->CopySize(properties()->length() + new_unused + 1);
|
| + if (!maybe_values->ToObject(&values)) return maybe_values;
|
| + }
|
| set_properties(FixedArray::cast(values));
|
| }
|
| set_map(new_map);
|
| @@ -1186,15 +1202,18 @@ Object* JSObject::AddFastPropertyUsingMap(Map* new_map,
|
| }
|
|
|
|
|
| -Object* JSObject::AddFastProperty(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::AddFastProperty(String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| // Normalize the object if the name is an actual string (not the
|
| // hidden symbols) and is not a real identifier.
|
| StringInputBuffer buffer(name);
|
| if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) {
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| return AddSlowProperty(name, value, attributes);
|
| }
|
|
|
| @@ -1204,9 +1223,13 @@ Object* JSObject::AddFastProperty(String* name,
|
|
|
| // Allocate new instance descriptors with (name, index) added
|
| FieldDescriptor new_field(name, index, attributes);
|
| - Object* new_descriptors =
|
| - old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);
|
| - if (new_descriptors->IsFailure()) return new_descriptors;
|
| + Object* new_descriptors;
|
| + { MaybeObject* maybe_new_descriptors =
|
| + old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);
|
| + if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
|
| + return maybe_new_descriptors;
|
| + }
|
| + }
|
|
|
| // Only allow map transition if the object's map is NOT equal to the
|
| // global object_function's map and there is not a transition for name.
|
| @@ -1218,27 +1241,36 @@ Object* JSObject::AddFastProperty(String* name,
|
| (index - map()->inobject_properties()) < properties()->length() ||
|
| map()->unused_property_fields() == 0);
|
| // Allocate a new map for the object.
|
| - Object* r = map()->CopyDropDescriptors();
|
| - if (r->IsFailure()) return r;
|
| + Object* r;
|
| + { MaybeObject* maybe_r = map()->CopyDropDescriptors();
|
| + if (!maybe_r->ToObject(&r)) return maybe_r;
|
| + }
|
| Map* new_map = Map::cast(r);
|
| if (allow_map_transition) {
|
| // Allocate new instance descriptors for the old map with map transition.
|
| MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
|
| - Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
|
| - if (r->IsFailure()) return r;
|
| + Object* r;
|
| + { MaybeObject* maybe_r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
|
| + if (!maybe_r->ToObject(&r)) return maybe_r;
|
| + }
|
| old_descriptors = DescriptorArray::cast(r);
|
| }
|
|
|
| if (map()->unused_property_fields() == 0) {
|
| if (properties()->length() > MaxFastProperties()) {
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| return AddSlowProperty(name, value, attributes);
|
| }
|
| // Make room for the new value
|
| - Object* values =
|
| - properties()->CopySize(properties()->length() + kFieldsAdded);
|
| - if (values->IsFailure()) return values;
|
| + Object* values;
|
| + { MaybeObject* maybe_values =
|
| + properties()->CopySize(properties()->length() + kFieldsAdded);
|
| + if (!maybe_values->ToObject(&values)) return maybe_values;
|
| + }
|
| set_properties(FixedArray::cast(values));
|
| new_map->set_unused_property_fields(kFieldsAdded - 1);
|
| } else {
|
| @@ -1253,20 +1285,27 @@ Object* JSObject::AddFastProperty(String* name,
|
| }
|
|
|
|
|
| -Object* JSObject::AddConstantFunctionProperty(String* name,
|
| - JSFunction* function,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::AddConstantFunctionProperty(
|
| + String* name,
|
| + JSFunction* function,
|
| + PropertyAttributes attributes) {
|
| ASSERT(!Heap::InNewSpace(function));
|
|
|
| // Allocate new instance descriptors with (name, function) added
|
| ConstantFunctionDescriptor d(name, function, attributes);
|
| - Object* new_descriptors =
|
| - map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);
|
| - if (new_descriptors->IsFailure()) return new_descriptors;
|
| + Object* new_descriptors;
|
| + { MaybeObject* maybe_new_descriptors =
|
| + map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);
|
| + if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
|
| + return maybe_new_descriptors;
|
| + }
|
| + }
|
|
|
| // Allocate a new map for the object.
|
| - Object* new_map = map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
|
|
| DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors);
|
| Map::cast(new_map)->set_instance_descriptors(descriptors);
|
| @@ -1292,10 +1331,12 @@ Object* JSObject::AddConstantFunctionProperty(String* name,
|
| return function;
|
| }
|
| ConstTransitionDescriptor mark(name, Map::cast(new_map));
|
| - new_descriptors =
|
| - old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS);
|
| - if (new_descriptors->IsFailure()) {
|
| - return function; // We have accomplished the main goal, so return success.
|
| + { MaybeObject* maybe_new_descriptors =
|
| + old_map->instance_descriptors()->CopyInsert(&mark, KEEP_TRANSITIONS);
|
| + if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
|
| + // We have accomplished the main goal, so return success.
|
| + return function;
|
| + }
|
| }
|
| old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
|
|
|
| @@ -1304,9 +1345,9 @@ Object* JSObject::AddConstantFunctionProperty(String* name,
|
|
|
|
|
| // Add property in slow mode
|
| -Object* JSObject::AddSlowProperty(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::AddSlowProperty(String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| ASSERT(!HasFastProperties());
|
| StringDictionary* dict = property_dictionary();
|
| Object* store_value = value;
|
| @@ -1324,21 +1365,25 @@ Object* JSObject::AddSlowProperty(String* name,
|
| dict->SetEntry(entry, name, store_value, details);
|
| return value;
|
| }
|
| - store_value = Heap::AllocateJSGlobalPropertyCell(value);
|
| - if (store_value->IsFailure()) return store_value;
|
| + { MaybeObject* maybe_store_value =
|
| + Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value;
|
| + }
|
| JSGlobalPropertyCell::cast(store_value)->set_value(value);
|
| }
|
| PropertyDetails details = PropertyDetails(attributes, NORMAL);
|
| - Object* result = dict->Add(name, store_value, details);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = dict->Add(name, store_value, details);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| if (dict != result) set_properties(StringDictionary::cast(result));
|
| return value;
|
| }
|
|
|
|
|
| -Object* JSObject::AddProperty(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::AddProperty(String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| ASSERT(!IsJSGlobalProxy());
|
| if (!map()->is_extensible()) {
|
| Handle<Object> args[1] = {Handle<String>(name)};
|
| @@ -1359,17 +1404,21 @@ Object* JSObject::AddProperty(String* name,
|
| } else {
|
| // Normalize the object to prevent very large instance descriptors.
|
| // This eliminates unwanted N^2 allocation and lookup behavior.
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| }
|
| }
|
| return AddSlowProperty(name, value, attributes);
|
| }
|
|
|
|
|
| -Object* JSObject::SetPropertyPostInterceptor(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::SetPropertyPostInterceptor(
|
| + String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| // Check local property, ignore interceptor.
|
| LookupResult result;
|
| LocalLookupRealNamedProperty(name, &result);
|
| @@ -1383,9 +1432,9 @@ Object* JSObject::SetPropertyPostInterceptor(String* name,
|
| }
|
|
|
|
|
| -Object* JSObject::ReplaceSlowProperty(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::ReplaceSlowProperty(String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| StringDictionary* dictionary = property_dictionary();
|
| int old_index = dictionary->FindEntry(name);
|
| int new_enumeration_index = 0; // 0 means "Use the next available index."
|
| @@ -1400,13 +1449,16 @@ Object* JSObject::ReplaceSlowProperty(String* name,
|
| }
|
|
|
|
|
| -Object* JSObject::ConvertDescriptorToFieldAndMapTransition(
|
| +MaybeObject* JSObject::ConvertDescriptorToFieldAndMapTransition(
|
| String* name,
|
| Object* new_value,
|
| PropertyAttributes attributes) {
|
| Map* old_map = map();
|
| - Object* result = ConvertDescriptorToField(name, new_value, attributes);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + ConvertDescriptorToField(name, new_value, attributes);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| // If we get to this point we have succeeded - do not return failure
|
| // after this point. Later stuff is optional.
|
| if (!HasFastProperties()) {
|
| @@ -1420,37 +1472,51 @@ Object* JSObject::ConvertDescriptorToFieldAndMapTransition(
|
| MapTransitionDescriptor transition(name,
|
| map(),
|
| attributes);
|
| - Object* new_descriptors =
|
| - old_map->instance_descriptors()->
|
| - CopyInsert(&transition, KEEP_TRANSITIONS);
|
| - if (new_descriptors->IsFailure()) return result; // Yes, return _result_.
|
| + Object* new_descriptors;
|
| + { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()->
|
| + CopyInsert(&transition, KEEP_TRANSITIONS);
|
| + if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
|
| + return result; // Yes, return _result_.
|
| + }
|
| + }
|
| old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
|
| return result;
|
| }
|
|
|
|
|
| -Object* JSObject::ConvertDescriptorToField(String* name,
|
| - Object* new_value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::ConvertDescriptorToField(String* name,
|
| + Object* new_value,
|
| + PropertyAttributes attributes) {
|
| if (map()->unused_property_fields() == 0 &&
|
| properties()->length() > MaxFastProperties()) {
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| return ReplaceSlowProperty(name, new_value, attributes);
|
| }
|
|
|
| int index = map()->NextFreePropertyIndex();
|
| FieldDescriptor new_field(name, index, attributes);
|
| // Make a new DescriptorArray replacing an entry with FieldDescriptor.
|
| - Object* descriptors_unchecked = map()->instance_descriptors()->
|
| - CopyInsert(&new_field, REMOVE_TRANSITIONS);
|
| - if (descriptors_unchecked->IsFailure()) return descriptors_unchecked;
|
| + Object* descriptors_unchecked;
|
| + { MaybeObject* maybe_descriptors_unchecked = map()->instance_descriptors()->
|
| + CopyInsert(&new_field, REMOVE_TRANSITIONS);
|
| + if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
|
| + return maybe_descriptors_unchecked;
|
| + }
|
| + }
|
| DescriptorArray* new_descriptors =
|
| DescriptorArray::cast(descriptors_unchecked);
|
|
|
| // Make a new map for the object.
|
| - Object* new_map_unchecked = map()->CopyDropDescriptors();
|
| - if (new_map_unchecked->IsFailure()) return new_map_unchecked;
|
| + Object* new_map_unchecked;
|
| + { MaybeObject* maybe_new_map_unchecked = map()->CopyDropDescriptors();
|
| + if (!maybe_new_map_unchecked->ToObject(&new_map_unchecked)) {
|
| + return maybe_new_map_unchecked;
|
| + }
|
| + }
|
| Map* new_map = Map::cast(new_map_unchecked);
|
| new_map->set_instance_descriptors(new_descriptors);
|
|
|
| @@ -1459,10 +1525,14 @@ Object* JSObject::ConvertDescriptorToField(String* name,
|
| int new_unused_property_fields = map()->unused_property_fields() - 1;
|
| if (map()->unused_property_fields() == 0) {
|
| new_unused_property_fields = kFieldsAdded - 1;
|
| - Object* new_properties_unchecked =
|
| - properties()->CopySize(properties()->length() + kFieldsAdded);
|
| - if (new_properties_unchecked->IsFailure()) return new_properties_unchecked;
|
| - new_properties = FixedArray::cast(new_properties_unchecked);
|
| + Object* new_properties_object;
|
| + { MaybeObject* maybe_new_properties_object =
|
| + properties()->CopySize(properties()->length() + kFieldsAdded);
|
| + if (!maybe_new_properties_object->ToObject(&new_properties_object)) {
|
| + return maybe_new_properties_object;
|
| + }
|
| + }
|
| + new_properties = FixedArray::cast(new_properties_object);
|
| }
|
|
|
| // Update pointers to commit changes.
|
| @@ -1477,9 +1547,10 @@ Object* JSObject::ConvertDescriptorToField(String* name,
|
|
|
|
|
|
|
| -Object* JSObject::SetPropertyWithInterceptor(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::SetPropertyWithInterceptor(
|
| + String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| HandleScope scope;
|
| Handle<JSObject> this_handle(this);
|
| Handle<String> name_handle(name);
|
| @@ -1505,27 +1576,28 @@ Object* JSObject::SetPropertyWithInterceptor(String* name,
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| if (!result.IsEmpty()) return *value_handle;
|
| }
|
| - Object* raw_result = this_handle->SetPropertyPostInterceptor(*name_handle,
|
| - *value_handle,
|
| - attributes);
|
| + MaybeObject* raw_result =
|
| + this_handle->SetPropertyPostInterceptor(*name_handle,
|
| + *value_handle,
|
| + attributes);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| return raw_result;
|
| }
|
|
|
|
|
| -Object* JSObject::SetProperty(String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::SetProperty(String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| LookupResult result;
|
| LocalLookup(name, &result);
|
| return SetProperty(&result, name, value, attributes);
|
| }
|
|
|
|
|
| -Object* JSObject::SetPropertyWithCallback(Object* structure,
|
| - String* name,
|
| - Object* value,
|
| - JSObject* holder) {
|
| +MaybeObject* JSObject::SetPropertyWithCallback(Object* structure,
|
| + String* name,
|
| + Object* value,
|
| + JSObject* holder) {
|
| HandleScope scope;
|
|
|
| // We should never get here to initialize a const with the hole
|
| @@ -1539,7 +1611,7 @@ Object* JSObject::SetPropertyWithCallback(Object* structure,
|
| if (structure->IsProxy()) {
|
| AccessorDescriptor* callback =
|
| reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());
|
| - Object* obj = (callback->setter)(this, value, callback->data);
|
| + MaybeObject* obj = (callback->setter)(this, value, callback->data);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| if (obj->IsFailure()) return obj;
|
| return *value_handle;
|
| @@ -1584,8 +1656,8 @@ Object* JSObject::SetPropertyWithCallback(Object* structure,
|
| }
|
|
|
|
|
| -Object* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter,
|
| - Object* value) {
|
| +MaybeObject* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter,
|
| + Object* value) {
|
| Handle<Object> value_handle(value);
|
| Handle<JSFunction> fun(JSFunction::cast(setter));
|
| Handle<JSObject> self(this);
|
| @@ -1727,9 +1799,9 @@ void JSObject::LookupRealNamedPropertyInPrototypes(String* name,
|
|
|
|
|
| // We only need to deal with CALLBACKS and INTERCEPTORS
|
| -Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
|
| - String* name,
|
| - Object* value) {
|
| +MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
|
| + String* name,
|
| + Object* value) {
|
| if (!result->IsProperty()) {
|
| LookupCallbackSetterInPrototypes(name, result);
|
| }
|
| @@ -1774,10 +1846,10 @@ Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,
|
| }
|
|
|
|
|
| -Object* JSObject::SetProperty(LookupResult* result,
|
| - String* name,
|
| - Object* value,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::SetProperty(LookupResult* result,
|
| + String* name,
|
| + Object* value,
|
| + PropertyAttributes attributes) {
|
| // Make sure that the top context does not change when doing callbacks or
|
| // interceptor calls.
|
| AssertNoContextChange ncc;
|
| @@ -1786,8 +1858,12 @@ Object* JSObject::SetProperty(LookupResult* result,
|
| // dictionary. We make these short keys into symbols to avoid constantly
|
| // reallocating them.
|
| if (!name->IsSymbol() && name->length() <= 2) {
|
| - Object* symbol_version = Heap::LookupSymbol(name);
|
| - if (!symbol_version->IsFailure()) name = String::cast(symbol_version);
|
| + Object* symbol_version;
|
| + { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name);
|
| + if (maybe_symbol_version->ToObject(&symbol_version)) {
|
| + name = String::cast(symbol_version);
|
| + }
|
| + }
|
| }
|
|
|
| // Check access rights if needed.
|
| @@ -1883,7 +1959,7 @@ Object* JSObject::SetProperty(LookupResult* result,
|
| // callback setter removed. The two lines looking up the LookupResult
|
| // result are also added. If one of the functions is changed, the other
|
| // should be.
|
| -Object* JSObject::IgnoreAttributesAndSetLocalProperty(
|
| +MaybeObject* JSObject::IgnoreAttributesAndSetLocalProperty(
|
| String* name,
|
| Object* value,
|
| PropertyAttributes attributes) {
|
| @@ -2081,7 +2157,8 @@ PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) {
|
| }
|
|
|
|
|
| -Object* NormalizedMapCache::Get(JSObject* obj, PropertyNormalizationMode mode) {
|
| +MaybeObject* NormalizedMapCache::Get(JSObject* obj,
|
| + PropertyNormalizationMode mode) {
|
| Map* fast = obj->map();
|
| int index = Hash(fast) % kEntries;
|
| Object* result = get(index);
|
| @@ -2089,19 +2166,24 @@ Object* NormalizedMapCache::Get(JSObject* obj, PropertyNormalizationMode mode) {
|
| #ifdef DEBUG
|
| if (FLAG_enable_slow_asserts) {
|
| // The cached map should match newly created normalized map bit-by-bit.
|
| - Object* fresh = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
|
| - if (!fresh->IsFailure()) {
|
| - ASSERT(memcmp(Map::cast(fresh)->address(),
|
| - Map::cast(result)->address(),
|
| - Map::kSize) == 0);
|
| + Object* fresh;
|
| + { MaybeObject* maybe_fresh =
|
| + fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
|
| + if (maybe_fresh->ToObject(&fresh)) {
|
| + ASSERT(memcmp(Map::cast(fresh)->address(),
|
| + Map::cast(result)->address(),
|
| + Map::kSize) == 0);
|
| + }
|
| }
|
| }
|
| #endif
|
| return result;
|
| }
|
|
|
| - result = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
|
| - if (result->IsFailure()) return result;
|
| + { MaybeObject* maybe_result =
|
| + fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| set(index, result);
|
| Counters::normalized_maps.Increment();
|
|
|
| @@ -2153,14 +2235,16 @@ bool NormalizedMapCache::CheckHit(Map* slow,
|
| }
|
|
|
|
|
| -Object* JSObject::UpdateMapCodeCache(String* name, Code* code) {
|
| +MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) {
|
| if (map()->is_shared()) {
|
| // Fast case maps are never marked as shared.
|
| ASSERT(!HasFastProperties());
|
| // Replace the map with an identical copy that can be safely modified.
|
| - Object* obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
|
| - UNIQUE_NORMALIZED_MAP);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
|
| + UNIQUE_NORMALIZED_MAP);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| Counters::normalized_maps.Increment();
|
|
|
| set_map(Map::cast(obj));
|
| @@ -2169,8 +2253,8 @@ Object* JSObject::UpdateMapCodeCache(String* name, Code* code) {
|
| }
|
|
|
|
|
| -Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| - int expected_additional_properties) {
|
| +MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| + int expected_additional_properties) {
|
| if (!HasFastProperties()) return this;
|
|
|
| // The global object is always normalized.
|
| @@ -2183,9 +2267,11 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| } else {
|
| property_count += 2; // Make space for two more properties.
|
| }
|
| - Object* obj =
|
| - StringDictionary::Allocate(property_count);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + StringDictionary::Allocate(property_count);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| StringDictionary* dictionary = StringDictionary::cast(obj);
|
|
|
| DescriptorArray* descs = map()->instance_descriptors();
|
| @@ -2196,8 +2282,11 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, details.index());
|
| Object* value = descs->GetConstantFunction(i);
|
| - Object* result = dictionary->Add(descs->GetKey(i), value, d);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + dictionary->Add(descs->GetKey(i), value, d);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| dictionary = StringDictionary::cast(result);
|
| break;
|
| }
|
| @@ -2205,8 +2294,11 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, details.index());
|
| Object* value = FastPropertyAt(descs->GetFieldIndex(i));
|
| - Object* result = dictionary->Add(descs->GetKey(i), value, d);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + dictionary->Add(descs->GetKey(i), value, d);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| dictionary = StringDictionary::cast(result);
|
| break;
|
| }
|
| @@ -2214,8 +2306,11 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), CALLBACKS, details.index());
|
| Object* value = descs->GetCallbacksObject(i);
|
| - Object* result = dictionary->Add(descs->GetKey(i), value, d);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + dictionary->Add(descs->GetKey(i), value, d);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| dictionary = StringDictionary::cast(result);
|
| break;
|
| }
|
| @@ -2233,9 +2328,10 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| int index = map()->instance_descriptors()->NextEnumerationIndex();
|
| dictionary->SetNextEnumerationIndex(index);
|
|
|
| - obj = Top::context()->global_context()->
|
| - normalized_map_cache()->Get(this, mode);
|
| - if (obj->IsFailure()) return obj;
|
| + { MaybeObject* maybe_obj = Top::context()->global_context()->
|
| + normalized_map_cache()->Get(this, mode);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| Map* new_map = Map::cast(obj);
|
|
|
| // We have now successfully allocated all the necessary objects.
|
| @@ -2264,7 +2360,7 @@ Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
|
| }
|
|
|
|
|
| -Object* JSObject::TransformToFastProperties(int unused_property_fields) {
|
| +MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) {
|
| if (HasFastProperties()) return this;
|
| ASSERT(!IsGlobalObject());
|
| return property_dictionary()->
|
| @@ -2272,13 +2368,15 @@ Object* JSObject::TransformToFastProperties(int unused_property_fields) {
|
| }
|
|
|
|
|
| -Object* JSObject::NormalizeElements() {
|
| +MaybeObject* JSObject::NormalizeElements() {
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
| if (HasDictionaryElements()) return this;
|
| ASSERT(map()->has_fast_elements());
|
|
|
| - Object* obj = map()->GetSlowElementsMap();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = map()->GetSlowElementsMap();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| Map* new_map = Map::cast(obj);
|
|
|
| // Get number of entries.
|
| @@ -2288,16 +2386,20 @@ Object* JSObject::NormalizeElements() {
|
| int length = IsJSArray() ?
|
| Smi::cast(JSArray::cast(this)->length())->value() :
|
| array->length();
|
| - obj = NumberDictionary::Allocate(length);
|
| - if (obj->IsFailure()) return obj;
|
| + { MaybeObject* maybe_obj = NumberDictionary::Allocate(length);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| NumberDictionary* dictionary = NumberDictionary::cast(obj);
|
| // Copy entries.
|
| for (int i = 0; i < length; i++) {
|
| Object* value = array->get(i);
|
| if (!value->IsTheHole()) {
|
| PropertyDetails details = PropertyDetails(NONE, NORMAL);
|
| - Object* result = dictionary->AddNumberEntry(i, array->get(i), details);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + dictionary->AddNumberEntry(i, array->get(i), details);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| dictionary = NumberDictionary::cast(result);
|
| }
|
| }
|
| @@ -2320,21 +2422,24 @@ Object* JSObject::NormalizeElements() {
|
| }
|
|
|
|
|
| -Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) {
|
| +MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
|
| + DeleteMode mode) {
|
| // Check local property, ignore interceptor.
|
| LookupResult result;
|
| LocalLookupRealNamedProperty(name, &result);
|
| if (!result.IsProperty()) return Heap::true_value();
|
|
|
| // Normalize object if needed.
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| return DeleteNormalizedProperty(name, mode);
|
| }
|
|
|
|
|
| -Object* JSObject::DeletePropertyWithInterceptor(String* name) {
|
| +MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) {
|
| HandleScope scope;
|
| Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
|
| Handle<String> name_handle(name);
|
| @@ -2357,20 +2462,22 @@ Object* JSObject::DeletePropertyWithInterceptor(String* name) {
|
| return *v8::Utils::OpenHandle(*result);
|
| }
|
| }
|
| - Object* raw_result =
|
| + MaybeObject* raw_result =
|
| this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| return raw_result;
|
| }
|
|
|
|
|
| -Object* JSObject::DeleteElementPostInterceptor(uint32_t index,
|
| - DeleteMode mode) {
|
| +MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index,
|
| + DeleteMode mode) {
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
| switch (GetElementsKind()) {
|
| case FAST_ELEMENTS: {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureWritableFastElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| uint32_t length = IsJSArray() ?
|
| static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
|
| static_cast<uint32_t>(FixedArray::cast(elements())->length());
|
| @@ -2395,7 +2502,7 @@ Object* JSObject::DeleteElementPostInterceptor(uint32_t index,
|
| }
|
|
|
|
|
| -Object* JSObject::DeleteElementWithInterceptor(uint32_t index) {
|
| +MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) {
|
| // Make sure that the top context does not change when doing
|
| // callbacks or interceptor calls.
|
| AssertNoContextChange ncc;
|
| @@ -2419,14 +2526,14 @@ Object* JSObject::DeleteElementWithInterceptor(uint32_t index) {
|
| ASSERT(result->IsBoolean());
|
| return *v8::Utils::OpenHandle(*result);
|
| }
|
| - Object* raw_result =
|
| + MaybeObject* raw_result =
|
| this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| return raw_result;
|
| }
|
|
|
|
|
| -Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
| +MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
| // Check access rights if needed.
|
| if (IsAccessCheckNeeded() &&
|
| !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
|
| @@ -2451,8 +2558,10 @@ Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
|
|
| switch (GetElementsKind()) {
|
| case FAST_ELEMENTS: {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureWritableFastElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| uint32_t length = IsJSArray() ?
|
| static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
|
| static_cast<uint32_t>(FixedArray::cast(elements())->length());
|
| @@ -2488,7 +2597,7 @@ Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
|
| }
|
|
|
|
|
| -Object* JSObject::DeleteProperty(String* name, DeleteMode mode) {
|
| +MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
|
| // ECMA-262, 3rd, 8.6.2.5
|
| ASSERT(name->IsString());
|
|
|
| @@ -2526,8 +2635,11 @@ Object* JSObject::DeleteProperty(String* name, DeleteMode mode) {
|
| return DeletePropertyWithInterceptor(name);
|
| }
|
| // Normalize object if needed.
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| // Make sure the properties are normalized before removing the entry.
|
| return DeleteNormalizedProperty(name, mode);
|
| }
|
| @@ -2633,19 +2745,23 @@ bool JSObject::ReferencesObject(Object* obj) {
|
| }
|
|
|
|
|
| -Object* JSObject::PreventExtensions() {
|
| +MaybeObject* JSObject::PreventExtensions() {
|
| // If there are fast elements we normalize.
|
| if (HasFastElements()) {
|
| - Object* ok = NormalizeElements();
|
| - if (ok->IsFailure()) return ok;
|
| + Object* ok;
|
| + { MaybeObject* maybe_ok = NormalizeElements();
|
| + if (!maybe_ok->ToObject(&ok)) return maybe_ok;
|
| + }
|
| }
|
| // Make sure that we never go back to fast case.
|
| element_dictionary()->set_requires_slow_elements();
|
|
|
| // Do a map transition, other objects with this map may still
|
| // be extensible.
|
| - Object* new_map = map()->CopyDropTransitions();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = map()->CopyDropTransitions();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
| Map::cast(new_map)->set_is_extensible(false);
|
| set_map(Map::cast(new_map));
|
| ASSERT(!map()->is_extensible());
|
| @@ -2779,8 +2895,8 @@ void JSObject::LookupCallback(String* name, LookupResult* result) {
|
| }
|
|
|
|
|
| -Object* JSObject::DefineGetterSetter(String* name,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::DefineGetterSetter(String* name,
|
| + PropertyAttributes attributes) {
|
| // Make sure that the top context does not change when doing callbacks or
|
| // interceptor calls.
|
| AssertNoContextChange ncc;
|
| @@ -2850,8 +2966,10 @@ Object* JSObject::DefineGetterSetter(String* name,
|
| }
|
|
|
| // Allocate the fixed array to hold getter and setter.
|
| - Object* structure = Heap::AllocateFixedArray(2, TENURED);
|
| - if (structure->IsFailure()) return structure;
|
| + Object* structure;
|
| + { MaybeObject* maybe_structure = Heap::AllocateFixedArray(2, TENURED);
|
| + if (!maybe_structure->ToObject(&structure)) return maybe_structure;
|
| + }
|
|
|
| if (is_element) {
|
| return SetElementCallback(index, structure, attributes);
|
| @@ -2885,19 +3003,23 @@ bool JSObject::CanSetCallback(String* name) {
|
| }
|
|
|
|
|
| -Object* JSObject::SetElementCallback(uint32_t index,
|
| - Object* structure,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::SetElementCallback(uint32_t index,
|
| + Object* structure,
|
| + PropertyAttributes attributes) {
|
| PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
|
|
|
| // Normalize elements to make this operation simple.
|
| - Object* ok = NormalizeElements();
|
| - if (ok->IsFailure()) return ok;
|
| + Object* ok;
|
| + { MaybeObject* maybe_ok = NormalizeElements();
|
| + if (!maybe_ok->ToObject(&ok)) return maybe_ok;
|
| + }
|
|
|
| // Update the dictionary with the new CALLBACKS property.
|
| - Object* dict =
|
| - element_dictionary()->Set(index, structure, details);
|
| - if (dict->IsFailure()) return dict;
|
| + Object* dict;
|
| + { MaybeObject* maybe_dict =
|
| + element_dictionary()->Set(index, structure, details);
|
| + if (!maybe_dict->ToObject(&dict)) return maybe_dict;
|
| + }
|
|
|
| NumberDictionary* elements = NumberDictionary::cast(dict);
|
| elements->set_requires_slow_elements();
|
| @@ -2908,9 +3030,9 @@ Object* JSObject::SetElementCallback(uint32_t index,
|
| }
|
|
|
|
|
| -Object* JSObject::SetPropertyCallback(String* name,
|
| - Object* structure,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::SetPropertyCallback(String* name,
|
| + Object* structure,
|
| + PropertyAttributes attributes) {
|
| PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
|
|
|
| bool convert_back_to_fast = HasFastProperties() &&
|
| @@ -2918,30 +3040,39 @@ Object* JSObject::SetPropertyCallback(String* name,
|
| < DescriptorArray::kMaxNumberOfDescriptors);
|
|
|
| // Normalize object to make this operation simple.
|
| - Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (ok->IsFailure()) return ok;
|
| + Object* ok;
|
| + { MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!maybe_ok->ToObject(&ok)) return maybe_ok;
|
| + }
|
|
|
| // For the global object allocate a new map to invalidate the global inline
|
| // caches which have a global property cell reference directly in the code.
|
| if (IsGlobalObject()) {
|
| - Object* new_map = map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
| set_map(Map::cast(new_map));
|
| }
|
|
|
| // Update the dictionary with the new CALLBACKS property.
|
| - Object* result = SetNormalizedProperty(name, structure, details);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = SetNormalizedProperty(name, structure, details);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
|
|
| if (convert_back_to_fast) {
|
| - ok = TransformToFastProperties(0);
|
| - if (ok->IsFailure()) return ok;
|
| + { MaybeObject* maybe_ok = TransformToFastProperties(0);
|
| + if (!maybe_ok->ToObject(&ok)) return maybe_ok;
|
| + }
|
| }
|
| return result;
|
| }
|
|
|
| -Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun,
|
| - PropertyAttributes attributes) {
|
| +MaybeObject* JSObject::DefineAccessor(String* name,
|
| + bool is_getter,
|
| + JSFunction* fun,
|
| + PropertyAttributes attributes) {
|
| // Check access rights if needed.
|
| if (IsAccessCheckNeeded() &&
|
| !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
|
| @@ -2957,14 +3088,17 @@ Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun,
|
| fun, attributes);
|
| }
|
|
|
| - Object* array = DefineGetterSetter(name, attributes);
|
| - if (array->IsFailure() || array->IsUndefined()) return array;
|
| + Object* array;
|
| + { MaybeObject* maybe_array = DefineGetterSetter(name, attributes);
|
| + if (!maybe_array->ToObject(&array)) return maybe_array;
|
| + }
|
| + if (array->IsUndefined()) return array;
|
| FixedArray::cast(array)->set(is_getter ? 0 : 1, fun);
|
| return this;
|
| }
|
|
|
|
|
| -Object* JSObject::DefineAccessor(AccessorInfo* info) {
|
| +MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
|
| String* name = String::cast(info->name());
|
| // Check access rights if needed.
|
| if (IsAccessCheckNeeded() &&
|
| @@ -3019,8 +3153,11 @@ Object* JSObject::DefineAccessor(AccessorInfo* info) {
|
| break;
|
| }
|
|
|
| - Object* ok = SetElementCallback(index, info, info->property_attributes());
|
| - if (ok->IsFailure()) return ok;
|
| + Object* ok;
|
| + { MaybeObject* maybe_ok =
|
| + SetElementCallback(index, info, info->property_attributes());
|
| + if (!maybe_ok->ToObject(&ok)) return maybe_ok;
|
| + }
|
| } else {
|
| // Lookup the name.
|
| LookupResult result;
|
| @@ -3030,8 +3167,11 @@ Object* JSObject::DefineAccessor(AccessorInfo* info) {
|
| if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
|
| return Heap::undefined_value();
|
| }
|
| - Object* ok = SetPropertyCallback(name, info, info->property_attributes());
|
| - if (ok->IsFailure()) return ok;
|
| + Object* ok;
|
| + { MaybeObject* maybe_ok =
|
| + SetPropertyCallback(name, info, info->property_attributes());
|
| + if (!maybe_ok->ToObject(&ok)) return maybe_ok;
|
| + }
|
| }
|
|
|
| return this;
|
| @@ -3114,9 +3254,12 @@ Object* JSObject::SlowReverseLookup(Object* value) {
|
| }
|
|
|
|
|
| -Object* Map::CopyDropDescriptors() {
|
| - Object* result = Heap::AllocateMap(instance_type(), instance_size());
|
| - if (result->IsFailure()) return result;
|
| +MaybeObject* Map::CopyDropDescriptors() {
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + Heap::AllocateMap(instance_type(), instance_size());
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| Map::cast(result)->set_prototype(prototype());
|
| Map::cast(result)->set_constructor(constructor());
|
| // Don't copy descriptors, so map transitions always remain a forest.
|
| @@ -3134,9 +3277,11 @@ Object* Map::CopyDropDescriptors() {
|
| if (pre_allocated_property_fields() > 0) {
|
| ASSERT(constructor()->IsJSFunction());
|
| JSFunction* ctor = JSFunction::cast(constructor());
|
| - Object* descriptors =
|
| - ctor->initial_map()->instance_descriptors()->RemoveTransitions();
|
| - if (descriptors->IsFailure()) return descriptors;
|
| + Object* descriptors;
|
| + { MaybeObject* maybe_descriptors =
|
| + ctor->initial_map()->instance_descriptors()->RemoveTransitions();
|
| + if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
|
| + }
|
| Map::cast(result)->set_instance_descriptors(
|
| DescriptorArray::cast(descriptors));
|
| Map::cast(result)->set_pre_allocated_property_fields(
|
| @@ -3150,15 +3295,18 @@ Object* Map::CopyDropDescriptors() {
|
| }
|
|
|
|
|
| -Object* Map::CopyNormalized(PropertyNormalizationMode mode,
|
| - NormalizedMapSharingMode sharing) {
|
| +MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode,
|
| + NormalizedMapSharingMode sharing) {
|
| int new_instance_size = instance_size();
|
| if (mode == CLEAR_INOBJECT_PROPERTIES) {
|
| new_instance_size -= inobject_properties() * kPointerSize;
|
| }
|
|
|
| - Object* result = Heap::AllocateMap(instance_type(), new_instance_size);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + Heap::AllocateMap(instance_type(), new_instance_size);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
|
|
| if (mode != CLEAR_INOBJECT_PROPERTIES) {
|
| Map::cast(result)->set_inobject_properties(inobject_properties());
|
| @@ -3182,21 +3330,28 @@ Object* Map::CopyNormalized(PropertyNormalizationMode mode,
|
| }
|
|
|
|
|
| -Object* Map::CopyDropTransitions() {
|
| - Object* new_map = CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| - Object* descriptors = instance_descriptors()->RemoveTransitions();
|
| - if (descriptors->IsFailure()) return descriptors;
|
| +MaybeObject* Map::CopyDropTransitions() {
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = CopyDropDescriptors();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
| + Object* descriptors;
|
| + { MaybeObject* maybe_descriptors =
|
| + instance_descriptors()->RemoveTransitions();
|
| + if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors;
|
| + }
|
| cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
|
| return new_map;
|
| }
|
|
|
|
|
| -Object* Map::UpdateCodeCache(String* name, Code* code) {
|
| +MaybeObject* Map::UpdateCodeCache(String* name, Code* code) {
|
| // Allocate the code cache if not present.
|
| if (code_cache()->IsFixedArray()) {
|
| - Object* result = Heap::AllocateCodeCache();
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = Heap::AllocateCodeCache();
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| set_code_cache(result);
|
| }
|
|
|
| @@ -3273,7 +3428,7 @@ void Map::TraverseTransitionTree(TraverseCallback callback, void* data) {
|
| }
|
|
|
|
|
| -Object* CodeCache::Update(String* name, Code* code) {
|
| +MaybeObject* CodeCache::Update(String* name, Code* code) {
|
| ASSERT(code->ic_state() == MONOMORPHIC);
|
|
|
| // The number of monomorphic stubs for normal load/store/call IC's can grow to
|
| @@ -3282,9 +3437,11 @@ Object* CodeCache::Update(String* name, Code* code) {
|
| if (code->type() == NORMAL) {
|
| // Make sure that a hash table is allocated for the normal load code cache.
|
| if (normal_type_cache()->IsUndefined()) {
|
| - Object* result =
|
| - CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result =
|
| + CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| set_normal_type_cache(result);
|
| }
|
| return UpdateNormalTypeCache(name, code);
|
| @@ -3295,7 +3452,7 @@ Object* CodeCache::Update(String* name, Code* code) {
|
| }
|
|
|
|
|
| -Object* CodeCache::UpdateDefaultCache(String* name, Code* code) {
|
| +MaybeObject* CodeCache::UpdateDefaultCache(String* name, Code* code) {
|
| // When updating the default code cache we disregard the type encoded in the
|
| // flags. This allows call constant stubs to overwrite call field
|
| // stubs, etc.
|
| @@ -3341,8 +3498,10 @@ Object* CodeCache::UpdateDefaultCache(String* name, Code* code) {
|
| int new_length = length + ((length >> 1)) + kCodeCacheEntrySize;
|
| new_length = new_length - new_length % kCodeCacheEntrySize;
|
| ASSERT((new_length % kCodeCacheEntrySize) == 0);
|
| - Object* result = cache->CopySize(new_length);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = cache->CopySize(new_length);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
|
|
| // Add the (name, code) pair to the new cache.
|
| cache = FixedArray::cast(result);
|
| @@ -3353,11 +3512,13 @@ Object* CodeCache::UpdateDefaultCache(String* name, Code* code) {
|
| }
|
|
|
|
|
| -Object* CodeCache::UpdateNormalTypeCache(String* name, Code* code) {
|
| +MaybeObject* CodeCache::UpdateNormalTypeCache(String* name, Code* code) {
|
| // Adding a new entry can cause a new cache to be allocated.
|
| CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
|
| - Object* new_cache = cache->Put(name, code);
|
| - if (new_cache->IsFailure()) return new_cache;
|
| + Object* new_cache;
|
| + { MaybeObject* maybe_new_cache = cache->Put(name, code);
|
| + if (!maybe_new_cache->ToObject(&new_cache)) return maybe_new_cache;
|
| + }
|
| set_normal_type_cache(new_cache);
|
| return this;
|
| }
|
| @@ -3475,10 +3636,12 @@ class CodeCacheHashTableKey : public HashTableKey {
|
| return NameFlagsHashHelper(name, code->flags());
|
| }
|
|
|
| - Object* AsObject() {
|
| + MUST_USE_RESULT MaybeObject* AsObject() {
|
| ASSERT(code_ != NULL);
|
| - Object* obj = Heap::AllocateFixedArray(2);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray* pair = FixedArray::cast(obj);
|
| pair->set(0, name_);
|
| pair->set(1, code_);
|
| @@ -3500,17 +3663,21 @@ Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) {
|
| }
|
|
|
|
|
| -Object* CodeCacheHashTable::Put(String* name, Code* code) {
|
| +MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) {
|
| CodeCacheHashTableKey key(name, code);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| // Don't use this, as the table might have grown.
|
| CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj);
|
|
|
| int entry = cache->FindInsertionEntry(key.Hash());
|
| - Object* k = key.AsObject();
|
| - if (k->IsFailure()) return k;
|
| + Object* k;
|
| + { MaybeObject* maybe_k = key.AsObject();
|
| + if (!maybe_k->ToObject(&k)) return maybe_k;
|
| + }
|
|
|
| cache->set(EntryToIndex(entry), k);
|
| cache->set(EntryToIndex(entry) + 1, code);
|
| @@ -3548,7 +3715,7 @@ static bool HasKey(FixedArray* array, Object* key) {
|
| }
|
|
|
|
|
| -Object* FixedArray::AddKeysFromJSArray(JSArray* array) {
|
| +MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) {
|
| ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements());
|
| switch (array->GetElementsKind()) {
|
| case JSObject::FAST_ELEMENTS:
|
| @@ -3558,8 +3725,10 @@ Object* FixedArray::AddKeysFromJSArray(JSArray* array) {
|
| int size = dict->NumberOfElements();
|
|
|
| // Allocate a temporary fixed array.
|
| - Object* object = Heap::AllocateFixedArray(size);
|
| - if (object->IsFailure()) return object;
|
| + Object* object;
|
| + { MaybeObject* maybe_object = Heap::AllocateFixedArray(size);
|
| + if (!maybe_object->ToObject(&object)) return maybe_object;
|
| + }
|
| FixedArray* key_array = FixedArray::cast(object);
|
|
|
| int capacity = dict->Capacity();
|
| @@ -3581,7 +3750,7 @@ Object* FixedArray::AddKeysFromJSArray(JSArray* array) {
|
| }
|
|
|
|
|
| -Object* FixedArray::UnionOfKeys(FixedArray* other) {
|
| +MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
|
| int len0 = length();
|
| #ifdef DEBUG
|
| if (FLAG_enable_slow_asserts) {
|
| @@ -3606,8 +3775,10 @@ Object* FixedArray::UnionOfKeys(FixedArray* other) {
|
| if (extra == 0) return this;
|
|
|
| // Allocate the result
|
| - Object* obj = Heap::AllocateFixedArray(len0 + extra);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(len0 + extra);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| // Fill in the content
|
| AssertNoAllocation no_gc;
|
| FixedArray* result = FixedArray::cast(obj);
|
| @@ -3633,10 +3804,12 @@ Object* FixedArray::UnionOfKeys(FixedArray* other) {
|
| }
|
|
|
|
|
| -Object* FixedArray::CopySize(int new_length) {
|
| +MaybeObject* FixedArray::CopySize(int new_length) {
|
| if (new_length == 0) return Heap::empty_fixed_array();
|
| - Object* obj = Heap::AllocateFixedArray(new_length);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(new_length);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray* result = FixedArray::cast(obj);
|
| // Copy the content
|
| AssertNoAllocation no_gc;
|
| @@ -3671,20 +3844,24 @@ bool FixedArray::IsEqualTo(FixedArray* other) {
|
| #endif
|
|
|
|
|
| -Object* DescriptorArray::Allocate(int number_of_descriptors) {
|
| +MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) {
|
| if (number_of_descriptors == 0) {
|
| return Heap::empty_descriptor_array();
|
| }
|
| // Allocate the array of keys.
|
| - Object* array =
|
| - Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors));
|
| - if (array->IsFailure()) return array;
|
| + Object* array;
|
| + { MaybeObject* maybe_array =
|
| + Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors));
|
| + if (!maybe_array->ToObject(&array)) return maybe_array;
|
| + }
|
| // Do not use DescriptorArray::cast on incomplete object.
|
| FixedArray* result = FixedArray::cast(array);
|
|
|
| // Allocate the content array and set it in the descriptor array.
|
| - array = Heap::AllocateFixedArray(number_of_descriptors << 1);
|
| - if (array->IsFailure()) return array;
|
| + { MaybeObject* maybe_array =
|
| + Heap::AllocateFixedArray(number_of_descriptors << 1);
|
| + if (!maybe_array->ToObject(&array)) return maybe_array;
|
| + }
|
| result->set(kContentArrayIndex, array);
|
| result->set(kEnumerationIndexIndex,
|
| Smi::FromInt(PropertyDetails::kInitialIndex));
|
| @@ -3710,8 +3887,8 @@ void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
|
| }
|
|
|
|
|
| -Object* DescriptorArray::CopyInsert(Descriptor* descriptor,
|
| - TransitionFlag transition_flag) {
|
| +MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor,
|
| + TransitionFlag transition_flag) {
|
| // Transitions are only kept when inserting another transition.
|
| // This precondition is not required by this function's implementation, but
|
| // is currently required by the semantics of maps, so we check it.
|
| @@ -3722,8 +3899,10 @@ Object* DescriptorArray::CopyInsert(Descriptor* descriptor,
|
| ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR);
|
|
|
| // Ensure the key is a symbol.
|
| - Object* result = descriptor->KeyToSymbol();
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = descriptor->KeyToSymbol();
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
|
|
| int transitions = 0;
|
| int null_descriptors = 0;
|
| @@ -3763,8 +3942,9 @@ Object* DescriptorArray::CopyInsert(Descriptor* descriptor,
|
| ++new_size;
|
| }
|
| }
|
| - result = Allocate(new_size);
|
| - if (result->IsFailure()) return result;
|
| + { MaybeObject* maybe_result = Allocate(new_size);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| DescriptorArray* new_descriptors = DescriptorArray::cast(result);
|
| // Set the enumeration index in the descriptors and set the enumeration index
|
| // in the result.
|
| @@ -3812,7 +3992,7 @@ Object* DescriptorArray::CopyInsert(Descriptor* descriptor,
|
| }
|
|
|
|
|
| -Object* DescriptorArray::RemoveTransitions() {
|
| +MaybeObject* DescriptorArray::RemoveTransitions() {
|
| // Remove all transitions and null descriptors. Return a copy of the array
|
| // with all transitions removed, or a Failure object if the new array could
|
| // not be allocated.
|
| @@ -3824,8 +4004,10 @@ Object* DescriptorArray::RemoveTransitions() {
|
| }
|
|
|
| // Allocate the new descriptor array.
|
| - Object* result = Allocate(number_of_descriptors() - num_removed);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = Allocate(number_of_descriptors() - num_removed);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| DescriptorArray* new_descriptors = DescriptorArray::cast(result);
|
|
|
| // Copy the content.
|
| @@ -5063,9 +5245,9 @@ uint32_t String::ComputeHashField(unibrow::CharacterStream* buffer,
|
| }
|
|
|
|
|
| -Object* String::SubString(int start, int end, PretenureFlag pretenure) {
|
| +MaybeObject* String::SubString(int start, int end, PretenureFlag pretenure) {
|
| if (start == 0 && end == length()) return this;
|
| - Object* result = Heap::AllocateSubString(this, start, end, pretenure);
|
| + MaybeObject* result = Heap::AllocateSubString(this, start, end, pretenure);
|
| return result;
|
| }
|
|
|
| @@ -5166,7 +5348,7 @@ Object* JSFunction::SetInstancePrototype(Object* value) {
|
| }
|
|
|
|
|
| -Object* JSFunction::SetPrototype(Object* value) {
|
| +MaybeObject* JSFunction::SetPrototype(Object* value) {
|
| ASSERT(should_have_prototype());
|
| Object* construct_prototype = value;
|
|
|
| @@ -5178,8 +5360,10 @@ Object* JSFunction::SetPrototype(Object* value) {
|
| // Copy the map so this does not affect unrelated functions.
|
| // Remove map transitions because they point to maps with a
|
| // different prototype.
|
| - Object* new_map = map()->CopyDropTransitions();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = map()->CopyDropTransitions();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
| set_map(Map::cast(new_map));
|
| map()->set_constructor(value);
|
| map()->set_non_instance_prototype(true);
|
| @@ -5212,9 +5396,11 @@ Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) {
|
| }
|
|
|
|
|
| -Object* Oddball::Initialize(const char* to_string, Object* to_number) {
|
| - Object* symbol = Heap::LookupAsciiSymbol(to_string);
|
| - if (symbol->IsFailure()) return symbol;
|
| +MaybeObject* Oddball::Initialize(const char* to_string, Object* to_number) {
|
| + Object* symbol;
|
| + { MaybeObject* maybe_symbol = Heap::LookupAsciiSymbol(to_string);
|
| + if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol;
|
| + }
|
| set_to_string(String::cast(symbol));
|
| set_to_number(to_number);
|
| return this;
|
| @@ -5703,16 +5889,20 @@ void Code::Disassemble(const char* name) {
|
| #endif // ENABLE_DISASSEMBLER
|
|
|
|
|
| -Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) {
|
| +MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity,
|
| + int length) {
|
| // We should never end in here with a pixel or external array.
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
|
|
| - Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray* elems = FixedArray::cast(obj);
|
|
|
| - obj = map()->GetFastElementsMap();
|
| - if (obj->IsFailure()) return obj;
|
| + { MaybeObject* maybe_obj = map()->GetFastElementsMap();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| Map* new_map = Map::cast(obj);
|
|
|
| AssertNoAllocation no_gc;
|
| @@ -5754,7 +5944,7 @@ Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) {
|
| }
|
|
|
|
|
| -Object* JSObject::SetSlowElements(Object* len) {
|
| +MaybeObject* JSObject::SetSlowElements(Object* len) {
|
| // We should never end in here with a pixel or external array.
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
|
|
| @@ -5765,8 +5955,10 @@ Object* JSObject::SetSlowElements(Object* len) {
|
| // Make sure we never try to shrink dense arrays into sparse arrays.
|
| ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <=
|
| new_length);
|
| - Object* obj = NormalizeElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = NormalizeElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| // Update length for JSArrays.
|
| if (IsJSArray()) JSArray::cast(this)->set_length(len);
|
| @@ -5789,15 +5981,17 @@ Object* JSObject::SetSlowElements(Object* len) {
|
| }
|
|
|
|
|
| -Object* JSArray::Initialize(int capacity) {
|
| +MaybeObject* JSArray::Initialize(int capacity) {
|
| ASSERT(capacity >= 0);
|
| set_length(Smi::FromInt(0));
|
| FixedArray* new_elements;
|
| if (capacity == 0) {
|
| new_elements = Heap::empty_fixed_array();
|
| } else {
|
| - Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| new_elements = FixedArray::cast(obj);
|
| }
|
| set_elements(new_elements);
|
| @@ -5824,19 +6018,20 @@ static int NewElementsCapacity(int old_capacity) {
|
| }
|
|
|
|
|
| -static Object* ArrayLengthRangeError() {
|
| +static Failure* ArrayLengthRangeError() {
|
| HandleScope scope;
|
| return Top::Throw(*Factory::NewRangeError("invalid_array_length",
|
| HandleVector<Object>(NULL, 0)));
|
| }
|
|
|
|
|
| -Object* JSObject::SetElementsLength(Object* len) {
|
| +MaybeObject* JSObject::SetElementsLength(Object* len) {
|
| // We should never end in here with a pixel or external array.
|
| ASSERT(AllowsSetElementsLength());
|
|
|
| - Object* smi_length = len->ToSmi();
|
| - if (smi_length->IsSmi()) {
|
| + MaybeObject* maybe_smi_length = len->ToSmi();
|
| + Object* smi_length = Smi::FromInt(0);
|
| + if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
|
| const int value = Smi::cast(smi_length)->value();
|
| if (value < 0) return ArrayLengthRangeError();
|
| switch (GetElementsKind()) {
|
| @@ -5844,8 +6039,10 @@ Object* JSObject::SetElementsLength(Object* len) {
|
| int old_capacity = FixedArray::cast(elements())->length();
|
| if (value <= old_capacity) {
|
| if (IsJSArray()) {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureWritableFastElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| int old_length = FastD2I(JSArray::cast(this)->length()->Number());
|
| // NOTE: We may be able to optimize this by removing the
|
| // last part of the elements backing storage array and
|
| @@ -5861,8 +6058,11 @@ Object* JSObject::SetElementsLength(Object* len) {
|
| int new_capacity = value > min ? value : min;
|
| if (new_capacity <= kMaxFastElementsLength ||
|
| !ShouldConvertToSlowElements(new_capacity)) {
|
| - Object* obj = SetFastElementsCapacityAndLength(new_capacity, value);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + SetFastElementsCapacityAndLength(new_capacity, value);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| return this;
|
| }
|
| break;
|
| @@ -5873,8 +6073,10 @@ Object* JSObject::SetElementsLength(Object* len) {
|
| // If the length of a slow array is reset to zero, we clear
|
| // the array and flush backing storage. This has the added
|
| // benefit that the array returns to fast mode.
|
| - Object* obj = ResetElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = ResetElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| } else {
|
| // Remove deleted elements.
|
| uint32_t old_length =
|
| @@ -5903,8 +6105,10 @@ Object* JSObject::SetElementsLength(Object* len) {
|
|
|
| // len is not a number so make the array size one and
|
| // set only element to len.
|
| - Object* obj = Heap::AllocateFixedArray(1);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(1);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray::cast(obj)->set(0, len);
|
| if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
|
| set_elements(FixedArray::cast(obj));
|
| @@ -5912,8 +6116,8 @@ Object* JSObject::SetElementsLength(Object* len) {
|
| }
|
|
|
|
|
| -Object* JSObject::SetPrototype(Object* value,
|
| - bool skip_hidden_prototypes) {
|
| +MaybeObject* JSObject::SetPrototype(Object* value,
|
| + bool skip_hidden_prototypes) {
|
| // Silently ignore the change if value is not a JSObject or null.
|
| // SpiderMonkey behaves this way.
|
| if (!value->IsJSObject() && !value->IsNull()) return value;
|
| @@ -5945,8 +6149,10 @@ Object* JSObject::SetPrototype(Object* value,
|
| }
|
|
|
| // Set the new prototype of the object.
|
| - Object* new_map = real_receiver->map()->CopyDropTransitions();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
| Map::cast(new_map)->set_prototype(value);
|
| real_receiver->set_map(Map::cast(new_map));
|
|
|
| @@ -6179,7 +6385,8 @@ bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
|
| }
|
|
|
|
|
| -Object* JSObject::SetElementWithInterceptor(uint32_t index, Object* value) {
|
| +MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index,
|
| + Object* value) {
|
| // Make sure that the top context does not change when doing
|
| // callbacks or interceptor calls.
|
| AssertNoContextChange ncc;
|
| @@ -6202,17 +6409,17 @@ Object* JSObject::SetElementWithInterceptor(uint32_t index, Object* value) {
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| if (!result.IsEmpty()) return *value_handle;
|
| }
|
| - Object* raw_result =
|
| + MaybeObject* raw_result =
|
| this_handle->SetElementWithoutInterceptor(index, *value_handle);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| return raw_result;
|
| }
|
|
|
|
|
| -Object* JSObject::GetElementWithCallback(Object* receiver,
|
| - Object* structure,
|
| - uint32_t index,
|
| - Object* holder) {
|
| +MaybeObject* JSObject::GetElementWithCallback(Object* receiver,
|
| + Object* structure,
|
| + uint32_t index,
|
| + Object* holder) {
|
| ASSERT(!structure->IsProxy());
|
|
|
| // api style callbacks.
|
| @@ -6255,10 +6462,10 @@ Object* JSObject::GetElementWithCallback(Object* receiver,
|
| }
|
|
|
|
|
| -Object* JSObject::SetElementWithCallback(Object* structure,
|
| - uint32_t index,
|
| - Object* value,
|
| - JSObject* holder) {
|
| +MaybeObject* JSObject::SetElementWithCallback(Object* structure,
|
| + uint32_t index,
|
| + Object* value,
|
| + JSObject* holder) {
|
| HandleScope scope;
|
|
|
| // We should never get here to initialize a const with the hole
|
| @@ -6314,11 +6521,13 @@ Object* JSObject::SetElementWithCallback(Object* structure,
|
| // Adding n elements in fast case is O(n*n).
|
| // Note: revisit design to have dual undefined values to capture absent
|
| // elements.
|
| -Object* JSObject::SetFastElement(uint32_t index, Object* value) {
|
| +MaybeObject* JSObject::SetFastElement(uint32_t index, Object* value) {
|
| ASSERT(HasFastElements());
|
|
|
| - Object* elms_obj = EnsureWritableFastElements();
|
| - if (elms_obj->IsFailure()) return elms_obj;
|
| + Object* elms_obj;
|
| + { MaybeObject* maybe_elms_obj = EnsureWritableFastElements();
|
| + if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
|
| + }
|
| FixedArray* elms = FixedArray::cast(elms_obj);
|
| uint32_t elms_length = static_cast<uint32_t>(elms->length());
|
|
|
| @@ -6349,22 +6558,27 @@ Object* JSObject::SetFastElement(uint32_t index, Object* value) {
|
| if (new_capacity <= kMaxFastElementsLength ||
|
| !ShouldConvertToSlowElements(new_capacity)) {
|
| ASSERT(static_cast<uint32_t>(new_capacity) > index);
|
| - Object* obj = SetFastElementsCapacityAndLength(new_capacity, index + 1);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + SetFastElementsCapacityAndLength(new_capacity, index + 1);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray::cast(elements())->set(index, value);
|
| return value;
|
| }
|
| }
|
|
|
| // Otherwise default to slow case.
|
| - Object* obj = NormalizeElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = NormalizeElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| ASSERT(HasDictionaryElements());
|
| return SetElement(index, value);
|
| }
|
|
|
|
|
| -Object* JSObject::SetElement(uint32_t index, Object* value) {
|
| +MaybeObject* JSObject::SetElement(uint32_t index, Object* value) {
|
| // Check access rights if needed.
|
| if (IsAccessCheckNeeded() &&
|
| !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) {
|
| @@ -6390,7 +6604,8 @@ Object* JSObject::SetElement(uint32_t index, Object* value) {
|
| }
|
|
|
|
|
| -Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
|
| +MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
|
| + Object* value) {
|
| switch (GetElementsKind()) {
|
| case FAST_ELEMENTS:
|
| // Fast case.
|
| @@ -6461,8 +6676,10 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
|
| return Top::Throw(*Factory::NewTypeError("object_not_extensible",
|
| HandleVector(args, 1)));
|
| }
|
| - Object* result = dictionary->AtNumberPut(index, value);
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value);
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| if (elms != FixedArray::cast(result)) {
|
| set_elements(FixedArray::cast(result));
|
| }
|
| @@ -6471,9 +6688,13 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
|
| // Update the array length if this JSObject is an array.
|
| if (IsJSArray()) {
|
| JSArray* array = JSArray::cast(this);
|
| - Object* return_value = array->JSArrayUpdateLengthFromIndex(index,
|
| - value);
|
| - if (return_value->IsFailure()) return return_value;
|
| + Object* return_value;
|
| + { MaybeObject* maybe_return_value =
|
| + array->JSArrayUpdateLengthFromIndex(index, value);
|
| + if (!maybe_return_value->ToObject(&return_value)) {
|
| + return maybe_return_value;
|
| + }
|
| + }
|
| }
|
|
|
| // Attempt to put this object back in fast case.
|
| @@ -6484,8 +6705,11 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
|
| } else {
|
| new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
|
| }
|
| - Object* obj = SetFastElementsCapacityAndLength(new_length, new_length);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + SetFastElementsCapacityAndLength(new_length, new_length);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| #ifdef DEBUG
|
| if (FLAG_trace_normalization) {
|
| PrintF("Object elements are fast case again:\n");
|
| @@ -6507,23 +6731,26 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
|
| }
|
|
|
|
|
| -Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) {
|
| +MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
|
| + Object* value) {
|
| uint32_t old_len = 0;
|
| CHECK(length()->ToArrayIndex(&old_len));
|
| // Check to see if we need to update the length. For now, we make
|
| // sure that the length stays within 32-bits (unsigned).
|
| if (index >= old_len && index != 0xffffffff) {
|
| - Object* len =
|
| - Heap::NumberFromDouble(static_cast<double>(index) + 1);
|
| - if (len->IsFailure()) return len;
|
| + Object* len;
|
| + { MaybeObject* maybe_len =
|
| + Heap::NumberFromDouble(static_cast<double>(index) + 1);
|
| + if (!maybe_len->ToObject(&len)) return maybe_len;
|
| + }
|
| set_length(len);
|
| }
|
| return value;
|
| }
|
|
|
|
|
| -Object* JSObject::GetElementPostInterceptor(JSObject* receiver,
|
| - uint32_t index) {
|
| +MaybeObject* JSObject::GetElementPostInterceptor(JSObject* receiver,
|
| + uint32_t index) {
|
| // Get element works for both JSObject and JSArray since
|
| // JSArray::length cannot change.
|
| switch (GetElementsKind()) {
|
| @@ -6579,8 +6806,8 @@ Object* JSObject::GetElementPostInterceptor(JSObject* receiver,
|
| }
|
|
|
|
|
| -Object* JSObject::GetElementWithInterceptor(JSObject* receiver,
|
| - uint32_t index) {
|
| +MaybeObject* JSObject::GetElementWithInterceptor(JSObject* receiver,
|
| + uint32_t index) {
|
| // Make sure that the top context does not change when doing
|
| // callbacks or interceptor calls.
|
| AssertNoContextChange ncc;
|
| @@ -6605,14 +6832,15 @@ Object* JSObject::GetElementWithInterceptor(JSObject* receiver,
|
| if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result);
|
| }
|
|
|
| - Object* raw_result =
|
| + MaybeObject* raw_result =
|
| holder_handle->GetElementPostInterceptor(*this_handle, index);
|
| RETURN_IF_SCHEDULED_EXCEPTION();
|
| return raw_result;
|
| }
|
|
|
|
|
| -Object* JSObject::GetElementWithReceiver(JSObject* receiver, uint32_t index) {
|
| +MaybeObject* JSObject::GetElementWithReceiver(JSObject* receiver,
|
| + uint32_t index) {
|
| // Check access rights if needed.
|
| if (IsAccessCheckNeeded() &&
|
| !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) {
|
| @@ -6863,9 +7091,10 @@ InterceptorInfo* JSObject::GetIndexedInterceptor() {
|
| }
|
|
|
|
|
| -Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver,
|
| - String* name,
|
| - PropertyAttributes* attributes) {
|
| +MaybeObject* JSObject::GetPropertyPostInterceptor(
|
| + JSObject* receiver,
|
| + String* name,
|
| + PropertyAttributes* attributes) {
|
| // Check local property in holder, ignore interceptor.
|
| LookupResult result;
|
| LocalLookupRealNamedProperty(name, &result);
|
| @@ -6880,7 +7109,7 @@ Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver,
|
| }
|
|
|
|
|
| -Object* JSObject::GetLocalPropertyPostInterceptor(
|
| +MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
|
| JSObject* receiver,
|
| String* name,
|
| PropertyAttributes* attributes) {
|
| @@ -6894,7 +7123,7 @@ Object* JSObject::GetLocalPropertyPostInterceptor(
|
| }
|
|
|
|
|
| -Object* JSObject::GetPropertyWithInterceptor(
|
| +MaybeObject* JSObject::GetPropertyWithInterceptor(
|
| JSObject* receiver,
|
| String* name,
|
| PropertyAttributes* attributes) {
|
| @@ -6923,7 +7152,7 @@ Object* JSObject::GetPropertyWithInterceptor(
|
| }
|
| }
|
|
|
| - Object* result = holder_handle->GetPropertyPostInterceptor(
|
| + MaybeObject* result = holder_handle->GetPropertyPostInterceptor(
|
| *receiver_handle,
|
| *name_handle,
|
| attributes);
|
| @@ -7278,7 +7507,7 @@ uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
|
| }
|
|
|
|
|
| -Object* NumberDictionaryShape::AsObject(uint32_t key) {
|
| +MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
|
| return Heap::NumberFromUint32(key);
|
| }
|
|
|
| @@ -7301,7 +7530,7 @@ uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
|
| }
|
|
|
|
|
| -Object* StringDictionaryShape::AsObject(String* key) {
|
| +MaybeObject* StringDictionaryShape::AsObject(String* key) {
|
| return key;
|
| }
|
|
|
| @@ -7375,9 +7604,11 @@ class StringSharedKey : public HashTableKey {
|
| return StringSharedHashHelper(source, shared);
|
| }
|
|
|
| - Object* AsObject() {
|
| - Object* obj = Heap::AllocateFixedArray(2);
|
| - if (obj->IsFailure()) return obj;
|
| + MUST_USE_RESULT MaybeObject* AsObject() {
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray* pair = FixedArray::cast(obj);
|
| pair->set(0, shared_);
|
| pair->set(1, source_);
|
| @@ -7455,7 +7686,7 @@ class Utf8SymbolKey : public HashTableKey {
|
| return String::cast(other)->Hash();
|
| }
|
|
|
| - Object* AsObject() {
|
| + MaybeObject* AsObject() {
|
| if (hash_field_ == 0) Hash();
|
| return Heap::AllocateSymbol(string_, chars_, hash_field_);
|
| }
|
| @@ -7481,7 +7712,7 @@ class SymbolKey : public HashTableKey {
|
| return String::cast(other)->Hash();
|
| }
|
|
|
| - Object* AsObject() {
|
| + MaybeObject* AsObject() {
|
| // Attempt to flatten the string, so that symbols will most often
|
| // be flat strings.
|
| string_ = string_->TryFlattenGetString();
|
| @@ -7522,8 +7753,8 @@ void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) {
|
|
|
|
|
| template<typename Shape, typename Key>
|
| -Object* HashTable<Shape, Key>::Allocate(int at_least_space_for,
|
| - PretenureFlag pretenure) {
|
| +MaybeObject* HashTable<Shape, Key>::Allocate(int at_least_space_for,
|
| + PretenureFlag pretenure) {
|
| const int kMinCapacity = 32;
|
| int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
|
| if (capacity < kMinCapacity) {
|
| @@ -7532,12 +7763,14 @@ Object* HashTable<Shape, Key>::Allocate(int at_least_space_for,
|
| return Failure::OutOfMemoryException();
|
| }
|
|
|
| - Object* obj = Heap::AllocateHashTable(EntryToIndex(capacity), pretenure);
|
| - if (!obj->IsFailure()) {
|
| - HashTable::cast(obj)->SetNumberOfElements(0);
|
| - HashTable::cast(obj)->SetNumberOfDeletedElements(0);
|
| - HashTable::cast(obj)->SetCapacity(capacity);
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + Heap::AllocateHashTable(EntryToIndex(capacity), pretenure);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| }
|
| + HashTable::cast(obj)->SetNumberOfElements(0);
|
| + HashTable::cast(obj)->SetNumberOfDeletedElements(0);
|
| + HashTable::cast(obj)->SetCapacity(capacity);
|
| return obj;
|
| }
|
|
|
| @@ -7600,7 +7833,7 @@ int StringDictionary::FindEntry(String* key) {
|
|
|
|
|
| template<typename Shape, typename Key>
|
| -Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
|
| +MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
|
| int capacity = Capacity();
|
| int nof = NumberOfElements() + n;
|
| int nod = NumberOfDeletedElements();
|
| @@ -7615,8 +7848,11 @@ Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) {
|
| const int kMinCapacityForPretenure = 256;
|
| bool pretenure =
|
| (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this);
|
| - Object* obj = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| AssertNoAllocation no_gc;
|
| HashTable* table = HashTable::cast(obj);
|
| @@ -7674,13 +7910,13 @@ template class Dictionary<StringDictionaryShape, String*>;
|
|
|
| template class Dictionary<NumberDictionaryShape, uint32_t>;
|
|
|
| -template Object* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
|
| +template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
|
| int);
|
|
|
| -template Object* Dictionary<StringDictionaryShape, String*>::Allocate(
|
| +template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
|
| int);
|
|
|
| -template Object* Dictionary<NumberDictionaryShape, uint32_t>::AtPut(
|
| +template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut(
|
| uint32_t, Object*);
|
|
|
| template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup(
|
| @@ -7705,29 +7941,29 @@ template int
|
| Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
|
| PropertyAttributes);
|
|
|
| -template Object* Dictionary<StringDictionaryShape, String*>::Add(
|
| +template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add(
|
| String*, Object*, PropertyDetails);
|
|
|
| -template Object*
|
| +template MaybeObject*
|
| Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices();
|
|
|
| template int
|
| Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes(
|
| PropertyAttributes);
|
|
|
| -template Object* Dictionary<NumberDictionaryShape, uint32_t>::Add(
|
| +template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add(
|
| uint32_t, Object*, PropertyDetails);
|
|
|
| -template Object* Dictionary<NumberDictionaryShape, uint32_t>::EnsureCapacity(
|
| - int, uint32_t);
|
| +template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::
|
| + EnsureCapacity(int, uint32_t);
|
|
|
| -template Object* Dictionary<StringDictionaryShape, String*>::EnsureCapacity(
|
| - int, String*);
|
| +template MaybeObject* Dictionary<StringDictionaryShape, String*>::
|
| + EnsureCapacity(int, String*);
|
|
|
| -template Object* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry(
|
| +template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry(
|
| uint32_t, Object*, PropertyDetails, uint32_t);
|
|
|
| -template Object* Dictionary<StringDictionaryShape, String*>::AddEntry(
|
| +template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry(
|
| String*, Object*, PropertyDetails, uint32_t);
|
|
|
| template
|
| @@ -7742,7 +7978,7 @@ int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
|
|
|
| // Collates undefined and unexisting elements below limit from position
|
| // zero of the elements. The object stays in Dictionary mode.
|
| -Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
|
| +MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
|
| ASSERT(HasDictionaryElements());
|
| // Must stay in dictionary mode, either because of requires_slow_elements,
|
| // or because we are not going to sort (and therefore compact) all of the
|
| @@ -7751,13 +7987,18 @@ Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
|
| HeapNumber* result_double = NULL;
|
| if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
|
| // Allocate space for result before we start mutating the object.
|
| - Object* new_double = Heap::AllocateHeapNumber(0.0);
|
| - if (new_double->IsFailure()) return new_double;
|
| + Object* new_double;
|
| + { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0);
|
| + if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
|
| + }
|
| result_double = HeapNumber::cast(new_double);
|
| }
|
|
|
| - Object* obj = NumberDictionary::Allocate(dict->NumberOfElements());
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + NumberDictionary::Allocate(dict->NumberOfElements());
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| NumberDictionary* new_dict = NumberDictionary::cast(obj);
|
|
|
| AssertNoAllocation no_alloc;
|
| @@ -7779,15 +8020,18 @@ Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
|
| return Smi::FromInt(-1);
|
| }
|
| uint32_t key = NumberToUint32(k);
|
| + // In the following we assert that adding the entry to the new dictionary
|
| + // does not cause GC. This is the case because we made sure to allocate
|
| + // the dictionary big enough above, so it need not grow.
|
| if (key < limit) {
|
| if (value->IsUndefined()) {
|
| undefs++;
|
| } else {
|
| - new_dict->AddNumberEntry(pos, value, details);
|
| + new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked();
|
| pos++;
|
| }
|
| } else {
|
| - new_dict->AddNumberEntry(key, value, details);
|
| + new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked();
|
| }
|
| }
|
| }
|
| @@ -7795,7 +8039,8 @@ Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
|
| uint32_t result = pos;
|
| PropertyDetails no_details = PropertyDetails(NONE, NORMAL);
|
| while (undefs > 0) {
|
| - new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details);
|
| + new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details)->
|
| + ToObjectUnchecked();
|
| pos++;
|
| undefs--;
|
| }
|
| @@ -7816,7 +8061,7 @@ Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
|
| // the start of the elements array.
|
| // If the object is in dictionary mode, it is converted to fast elements
|
| // mode.
|
| -Object* JSObject::PrepareElementsForSort(uint32_t limit) {
|
| +MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
|
|
| if (HasDictionaryElements()) {
|
| @@ -7829,22 +8074,28 @@ Object* JSObject::PrepareElementsForSort(uint32_t limit) {
|
| }
|
| // Convert to fast elements.
|
|
|
| - Object* obj = map()->GetFastElementsMap();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = map()->GetFastElementsMap();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| Map* new_map = Map::cast(obj);
|
|
|
| PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED;
|
| - Object* new_array =
|
| - Heap::AllocateFixedArray(dict->NumberOfElements(), tenure);
|
| - if (new_array->IsFailure()) return new_array;
|
| + Object* new_array;
|
| + { MaybeObject* maybe_new_array =
|
| + Heap::AllocateFixedArray(dict->NumberOfElements(), tenure);
|
| + if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array;
|
| + }
|
| FixedArray* fast_elements = FixedArray::cast(new_array);
|
| dict->CopyValuesTo(fast_elements);
|
|
|
| set_map(new_map);
|
| set_elements(fast_elements);
|
| } else {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureWritableFastElements();
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| }
|
| ASSERT(HasFastElements());
|
|
|
| @@ -7864,8 +8115,10 @@ Object* JSObject::PrepareElementsForSort(uint32_t limit) {
|
| if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
|
| // Pessimistically allocate space for return value before
|
| // we start mutating the array.
|
| - Object* new_double = Heap::AllocateHeapNumber(0.0);
|
| - if (new_double->IsFailure()) return new_double;
|
| + Object* new_double;
|
| + { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0);
|
| + if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
|
| + }
|
| result_double = HeapNumber::cast(new_double);
|
| }
|
|
|
| @@ -7957,9 +8210,9 @@ Object* PixelArray::SetValue(uint32_t index, Object* value) {
|
|
|
|
|
| template<typename ExternalArrayClass, typename ValueType>
|
| -static Object* ExternalArrayIntSetter(ExternalArrayClass* receiver,
|
| - uint32_t index,
|
| - Object* value) {
|
| +static MaybeObject* ExternalArrayIntSetter(ExternalArrayClass* receiver,
|
| + uint32_t index,
|
| + Object* value) {
|
| ValueType cast_value = 0;
|
| if (index < static_cast<uint32_t>(receiver->length())) {
|
| if (value->IsSmi()) {
|
| @@ -7979,37 +8232,40 @@ static Object* ExternalArrayIntSetter(ExternalArrayClass* receiver,
|
| }
|
|
|
|
|
| -Object* ExternalByteArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) {
|
| return ExternalArrayIntSetter<ExternalByteArray, int8_t>
|
| (this, index, value);
|
| }
|
|
|
|
|
| -Object* ExternalUnsignedByteArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index,
|
| + Object* value) {
|
| return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t>
|
| (this, index, value);
|
| }
|
|
|
|
|
| -Object* ExternalShortArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalShortArray::SetValue(uint32_t index,
|
| + Object* value) {
|
| return ExternalArrayIntSetter<ExternalShortArray, int16_t>
|
| (this, index, value);
|
| }
|
|
|
|
|
| -Object* ExternalUnsignedShortArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index,
|
| + Object* value) {
|
| return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t>
|
| (this, index, value);
|
| }
|
|
|
|
|
| -Object* ExternalIntArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) {
|
| return ExternalArrayIntSetter<ExternalIntArray, int32_t>
|
| (this, index, value);
|
| }
|
|
|
|
|
| -Object* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) {
|
| uint32_t cast_value = 0;
|
| if (index < static_cast<uint32_t>(length())) {
|
| if (value->IsSmi()) {
|
| @@ -8029,7 +8285,7 @@ Object* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) {
|
| }
|
|
|
|
|
| -Object* ExternalFloatArray::SetValue(uint32_t index, Object* value) {
|
| +MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) {
|
| float cast_value = 0;
|
| if (index < static_cast<uint32_t>(length())) {
|
| if (value->IsSmi()) {
|
| @@ -8057,16 +8313,22 @@ Object* GlobalObject::GetPropertyCell(LookupResult* result) {
|
| }
|
|
|
|
|
| -Object* GlobalObject::EnsurePropertyCell(String* name) {
|
| +MaybeObject* GlobalObject::EnsurePropertyCell(String* name) {
|
| ASSERT(!HasFastProperties());
|
| int entry = property_dictionary()->FindEntry(name);
|
| if (entry == StringDictionary::kNotFound) {
|
| - Object* cell = Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value());
|
| - if (cell->IsFailure()) return cell;
|
| + Object* cell;
|
| + { MaybeObject* maybe_cell =
|
| + Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value());
|
| + if (!maybe_cell->ToObject(&cell)) return maybe_cell;
|
| + }
|
| PropertyDetails details(NONE, NORMAL);
|
| details = details.AsDeleted();
|
| - Object* dictionary = property_dictionary()->Add(name, cell, details);
|
| - if (dictionary->IsFailure()) return dictionary;
|
| + Object* dictionary;
|
| + { MaybeObject* maybe_dictionary =
|
| + property_dictionary()->Add(name, cell, details);
|
| + if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary;
|
| + }
|
| set_properties(StringDictionary::cast(dictionary));
|
| return cell;
|
| } else {
|
| @@ -8077,7 +8339,7 @@ Object* GlobalObject::EnsurePropertyCell(String* name) {
|
| }
|
|
|
|
|
| -Object* SymbolTable::LookupString(String* string, Object** s) {
|
| +MaybeObject* SymbolTable::LookupString(String* string, Object** s) {
|
| SymbolKey key(string);
|
| return LookupKey(&key, s);
|
| }
|
| @@ -8174,13 +8436,13 @@ bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1,
|
| }
|
|
|
|
|
| -Object* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
|
| +MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, Object** s) {
|
| Utf8SymbolKey key(str);
|
| return LookupKey(&key, s);
|
| }
|
|
|
|
|
| -Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
|
| +MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
|
| int entry = FindEntry(key);
|
|
|
| // Symbol already in table.
|
| @@ -8190,12 +8452,16 @@ Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
|
| }
|
|
|
| // Adding new symbol. Grow table if needed.
|
| - Object* obj = EnsureCapacity(1, key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| // Create symbol object.
|
| - Object* symbol = key->AsObject();
|
| - if (symbol->IsFailure()) return symbol;
|
| + Object* symbol;
|
| + { MaybeObject* maybe_symbol = key->AsObject();
|
| + if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol;
|
| + }
|
|
|
| // If the symbol table grew as part of EnsureCapacity, obj is not
|
| // the current symbol table and therefore we cannot use
|
| @@ -8236,10 +8502,12 @@ Object* CompilationCacheTable::LookupRegExp(String* src,
|
| }
|
|
|
|
|
| -Object* CompilationCacheTable::Put(String* src, Object* value) {
|
| +MaybeObject* CompilationCacheTable::Put(String* src, Object* value) {
|
| StringKey key(src);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| CompilationCacheTable* cache =
|
| reinterpret_cast<CompilationCacheTable*>(obj);
|
| @@ -8251,19 +8519,23 @@ Object* CompilationCacheTable::Put(String* src, Object* value) {
|
| }
|
|
|
|
|
| -Object* CompilationCacheTable::PutEval(String* src,
|
| - Context* context,
|
| - Object* value) {
|
| +MaybeObject* CompilationCacheTable::PutEval(String* src,
|
| + Context* context,
|
| + Object* value) {
|
| StringSharedKey key(src, context->closure()->shared());
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| CompilationCacheTable* cache =
|
| reinterpret_cast<CompilationCacheTable*>(obj);
|
| int entry = cache->FindInsertionEntry(key.Hash());
|
|
|
| - Object* k = key.AsObject();
|
| - if (k->IsFailure()) return k;
|
| + Object* k;
|
| + { MaybeObject* maybe_k = key.AsObject();
|
| + if (!maybe_k->ToObject(&k)) return maybe_k;
|
| + }
|
|
|
| cache->set(EntryToIndex(entry), k);
|
| cache->set(EntryToIndex(entry) + 1, value);
|
| @@ -8272,12 +8544,14 @@ Object* CompilationCacheTable::PutEval(String* src,
|
| }
|
|
|
|
|
| -Object* CompilationCacheTable::PutRegExp(String* src,
|
| - JSRegExp::Flags flags,
|
| - FixedArray* value) {
|
| +MaybeObject* CompilationCacheTable::PutRegExp(String* src,
|
| + JSRegExp::Flags flags,
|
| + FixedArray* value) {
|
| RegExpKey key(src, flags);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| CompilationCacheTable* cache =
|
| reinterpret_cast<CompilationCacheTable*>(obj);
|
| @@ -8333,10 +8607,12 @@ Object* MapCache::Lookup(FixedArray* array) {
|
| }
|
|
|
|
|
| -Object* MapCache::Put(FixedArray* array, Map* value) {
|
| +MaybeObject* MapCache::Put(FixedArray* array, Map* value) {
|
| SymbolsKey key(array);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| MapCache* cache = reinterpret_cast<MapCache*>(obj);
|
| int entry = cache->FindInsertionEntry(key.Hash());
|
| @@ -8348,32 +8624,37 @@ Object* MapCache::Put(FixedArray* array, Map* value) {
|
|
|
|
|
| template<typename Shape, typename Key>
|
| -Object* Dictionary<Shape, Key>::Allocate(int at_least_space_for) {
|
| - Object* obj = HashTable<Shape, Key>::Allocate(at_least_space_for);
|
| - // Initialize the next enumeration index.
|
| - if (!obj->IsFailure()) {
|
| - Dictionary<Shape, Key>::cast(obj)->
|
| - SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
|
| +MaybeObject* Dictionary<Shape, Key>::Allocate(int at_least_space_for) {
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj =
|
| + HashTable<Shape, Key>::Allocate(at_least_space_for);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| }
|
| + // Initialize the next enumeration index.
|
| + Dictionary<Shape, Key>::cast(obj)->
|
| + SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
|
| return obj;
|
| }
|
|
|
|
|
| template<typename Shape, typename Key>
|
| -Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
|
| +MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
|
| int length = HashTable<Shape, Key>::NumberOfElements();
|
|
|
| // Allocate and initialize iteration order array.
|
| - Object* obj = Heap::AllocateFixedArray(length);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray* iteration_order = FixedArray::cast(obj);
|
| for (int i = 0; i < length; i++) {
|
| iteration_order->set(i, Smi::FromInt(i));
|
| }
|
|
|
| // Allocate array with enumeration order.
|
| - obj = Heap::AllocateFixedArray(length);
|
| - if (obj->IsFailure()) return obj;
|
| + { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| FixedArray* enumeration_order = FixedArray::cast(obj);
|
|
|
| // Fill the enumeration order array with property details.
|
| @@ -8414,13 +8695,15 @@ Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
|
| }
|
|
|
| template<typename Shape, typename Key>
|
| -Object* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) {
|
| +MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) {
|
| // Check whether there are enough enumeration indices to add n elements.
|
| if (Shape::kIsEnumerable &&
|
| !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) {
|
| // If not, we generate new indices for the properties.
|
| - Object* result = GenerateNewEnumerationIndices();
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = GenerateNewEnumerationIndices();
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| }
|
| return HashTable<Shape, Key>::EnsureCapacity(n, key);
|
| }
|
| @@ -8464,7 +8747,7 @@ Object* Dictionary<Shape, Key>::DeleteProperty(int entry,
|
|
|
|
|
| template<typename Shape, typename Key>
|
| -Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
|
| +MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
|
| int entry = this->FindEntry(key);
|
|
|
| // If the entry is present set the value;
|
| @@ -8474,11 +8757,15 @@ Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
|
| }
|
|
|
| // Check whether the dictionary should be extended.
|
| - Object* obj = EnsureCapacity(1, key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
|
|
| - Object* k = Shape::AsObject(key);
|
| - if (k->IsFailure()) return k;
|
| + Object* k;
|
| + { MaybeObject* maybe_k = Shape::AsObject(key);
|
| + if (!maybe_k->ToObject(&k)) return maybe_k;
|
| + }
|
| PropertyDetails details = PropertyDetails(NONE, NORMAL);
|
| return Dictionary<Shape, Key>::cast(obj)->
|
| AddEntry(key, value, details, Shape::Hash(key));
|
| @@ -8486,14 +8773,16 @@ Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
|
|
|
|
|
| template<typename Shape, typename Key>
|
| -Object* Dictionary<Shape, Key>::Add(Key key,
|
| - Object* value,
|
| - PropertyDetails details) {
|
| +MaybeObject* Dictionary<Shape, Key>::Add(Key key,
|
| + Object* value,
|
| + PropertyDetails details) {
|
| // Valdate key is absent.
|
| SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound));
|
| // Check whether the dictionary should be extended.
|
| - Object* obj = EnsureCapacity(1, key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { MaybeObject* maybe_obj = EnsureCapacity(1, key);
|
| + if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
| + }
|
| return Dictionary<Shape, Key>::cast(obj)->
|
| AddEntry(key, value, details, Shape::Hash(key));
|
| }
|
| @@ -8501,13 +8790,15 @@ Object* Dictionary<Shape, Key>::Add(Key key,
|
|
|
| // Add a key, value pair to the dictionary.
|
| template<typename Shape, typename Key>
|
| -Object* Dictionary<Shape, Key>::AddEntry(Key key,
|
| - Object* value,
|
| - PropertyDetails details,
|
| - uint32_t hash) {
|
| +MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key,
|
| + Object* value,
|
| + PropertyDetails details,
|
| + uint32_t hash) {
|
| // Compute the key object.
|
| - Object* k = Shape::AsObject(key);
|
| - if (k->IsFailure()) return k;
|
| + Object* k;
|
| + { MaybeObject* maybe_k = Shape::AsObject(key);
|
| + if (!maybe_k->ToObject(&k)) return maybe_k;
|
| + }
|
|
|
| uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash);
|
| // Insert element at empty or deleted entry
|
| @@ -8545,32 +8836,33 @@ void NumberDictionary::UpdateMaxNumberKey(uint32_t key) {
|
| }
|
|
|
|
|
| -Object* NumberDictionary::AddNumberEntry(uint32_t key,
|
| - Object* value,
|
| - PropertyDetails details) {
|
| +MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key,
|
| + Object* value,
|
| + PropertyDetails details) {
|
| UpdateMaxNumberKey(key);
|
| SLOW_ASSERT(this->FindEntry(key) == kNotFound);
|
| return Add(key, value, details);
|
| }
|
|
|
|
|
| -Object* NumberDictionary::AtNumberPut(uint32_t key, Object* value) {
|
| +MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) {
|
| UpdateMaxNumberKey(key);
|
| return AtPut(key, value);
|
| }
|
|
|
|
|
| -Object* NumberDictionary::Set(uint32_t key,
|
| - Object* value,
|
| - PropertyDetails details) {
|
| +MaybeObject* NumberDictionary::Set(uint32_t key,
|
| + Object* value,
|
| + PropertyDetails details) {
|
| int entry = FindEntry(key);
|
| if (entry == kNotFound) return AddNumberEntry(key, value, details);
|
| // Preserve enumeration index.
|
| details = PropertyDetails(details.attributes(),
|
| details.type(),
|
| DetailsAt(entry).index());
|
| - Object* object_key = NumberDictionaryShape::AsObject(key);
|
| - if (object_key->IsFailure()) return object_key;
|
| + MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key);
|
| + Object* object_key;
|
| + if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key;
|
| SetEntry(entry, object_key, value, details);
|
| return this;
|
| }
|
| @@ -8678,7 +8970,7 @@ Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) {
|
| }
|
|
|
|
|
| -Object* StringDictionary::TransformPropertiesToFastFor(
|
| +MaybeObject* StringDictionary::TransformPropertiesToFastFor(
|
| JSObject* obj, int unused_property_fields) {
|
| // Make sure we preserve dictionary representation if there are too many
|
| // descriptors.
|
| @@ -8690,8 +8982,10 @@ Object* StringDictionary::TransformPropertiesToFastFor(
|
| (DescriptorArray::kMaxNumberOfDescriptors -
|
| NumberOfElements());
|
| if (!PropertyDetails::IsValidIndex(max_enumeration_index)) {
|
| - Object* result = GenerateNewEnumerationIndices();
|
| - if (result->IsFailure()) return result;
|
| + Object* result;
|
| + { MaybeObject* maybe_result = GenerateNewEnumerationIndices();
|
| + if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + }
|
| }
|
|
|
| int instance_descriptor_length = 0;
|
| @@ -8714,9 +9008,13 @@ Object* StringDictionary::TransformPropertiesToFastFor(
|
| }
|
|
|
| // Allocate the instance descriptor.
|
| - Object* descriptors_unchecked =
|
| - DescriptorArray::Allocate(instance_descriptor_length);
|
| - if (descriptors_unchecked->IsFailure()) return descriptors_unchecked;
|
| + Object* descriptors_unchecked;
|
| + { MaybeObject* maybe_descriptors_unchecked =
|
| + DescriptorArray::Allocate(instance_descriptor_length);
|
| + if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
|
| + return maybe_descriptors_unchecked;
|
| + }
|
| + }
|
| DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked);
|
|
|
| int inobject_props = obj->map()->inobject_properties();
|
| @@ -8729,8 +9027,11 @@ Object* StringDictionary::TransformPropertiesToFastFor(
|
| }
|
|
|
| // Allocate the fixed array for the fields.
|
| - Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields);
|
| - if (fields->IsFailure()) return fields;
|
| + Object* fields;
|
| + { MaybeObject* maybe_fields =
|
| + Heap::AllocateFixedArray(number_of_allocated_fields);
|
| + if (!maybe_fields->ToObject(&fields)) return maybe_fields;
|
| + }
|
|
|
| // Fill in the instance descriptor and the fields.
|
| int next_descriptor = 0;
|
| @@ -8740,8 +9041,10 @@ Object* StringDictionary::TransformPropertiesToFastFor(
|
| if (IsKey(k)) {
|
| Object* value = ValueAt(i);
|
| // Ensure the key is a symbol before writing into the instance descriptor.
|
| - Object* key = Heap::LookupSymbol(String::cast(k));
|
| - if (key->IsFailure()) return key;
|
| + Object* key;
|
| + { MaybeObject* maybe_key = Heap::LookupSymbol(String::cast(k));
|
| + if (!maybe_key->ToObject(&key)) return maybe_key;
|
| + }
|
| PropertyDetails details = DetailsAt(i);
|
| PropertyType type = details.type();
|
|
|
| @@ -8780,8 +9083,10 @@ Object* StringDictionary::TransformPropertiesToFastFor(
|
|
|
| descriptors->Sort();
|
| // Allocate new map.
|
| - Object* new_map = obj->map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| + Object* new_map;
|
| + { MaybeObject* maybe_new_map = obj->map()->CopyDropDescriptors();
|
| + if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
|
| + }
|
|
|
| // Transform the object.
|
| obj->set_map(Map::cast(new_map));
|
|
|