| Index: src/objects.cc
|
| ===================================================================
|
| --- src/objects.cc (revision 5566)
|
| +++ src/objects.cc (working copy)
|
| @@ -55,9 +55,11 @@
|
|
|
|
|
| MUST_USE_RESULT static Object* CreateJSValue(JSFunction* constructor,
|
| + Object* result;
|
| + { TryAllocation t = Heap::AllocateJSObject(constructor);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| Object* value) {
|
| - Object* result = Heap::AllocateJSObject(constructor);
|
| - if (result->IsFailure()) return result;
|
| JSValue::cast(result)->set_value(value);
|
| return result;
|
| }
|
| @@ -372,12 +374,15 @@
|
| int entry = property_dictionary()->FindEntry(name);
|
| if (entry == StringDictionary::kNotFound) {
|
| Object* store_value = value;
|
| + { TryAllocation t = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (!t->ToObject(&store_value)) return t;
|
| + }
|
| if (IsGlobalObject()) {
|
| - store_value = Heap::AllocateJSGlobalPropertyCell(value);
|
| - if (store_value->IsFailure()) return store_value;
|
| + Object* dict;
|
| + { TryAllocation t = property_dictionary()->Add(name, store_value, details);
|
| + if (!t->ToObject(&dict)) return t;
|
| }
|
| - Object* dict = property_dictionary()->Add(name, store_value, details);
|
| - if (dict->IsFailure()) return dict;
|
| + }
|
| set_properties(StringDictionary::cast(dict));
|
| return value;
|
| }
|
| @@ -411,9 +416,11 @@
|
| // When forced to delete global properties, we have to make a
|
| // map change to invalidate any ICs that think they can load
|
| // from the DontDelete cell without checking if it contains
|
| + Object* new_map;
|
| + { TryAllocation t = map()->CopyDropDescriptors();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| // the hole value.
|
| - Object* new_map = map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| set_map(Map::cast(new_map));
|
| }
|
| JSGlobalPropertyCell* cell =
|
| @@ -642,9 +649,10 @@
|
| int len = length();
|
| Object* object;
|
| String* result;
|
| + { TryAllocation t = Heap::AllocateRawAsciiString(len, tenure);
|
| + if (!t->ToObject(&object)) return t;
|
| + }
|
| if (IsAsciiRepresentation()) {
|
| - object = Heap::AllocateRawAsciiString(len, tenure);
|
| - if (object->IsFailure()) return object;
|
| result = String::cast(object);
|
| String* first = cs->first();
|
| int first_length = first->length();
|
| @@ -655,9 +663,10 @@
|
| dest + first_length,
|
| 0,
|
| len - first_length);
|
| + { TryAllocation t = Heap::AllocateRawTwoByteString(len, tenure);
|
| + if (!t->ToObject(&object)) return t;
|
| + }
|
| } else {
|
| - object = Heap::AllocateRawTwoByteString(len, tenure);
|
| - if (object->IsFailure()) return object;
|
| result = String::cast(object);
|
| uc16* dest = SeqTwoByteString::cast(result)->GetChars();
|
| String* first = cs->first();
|
| @@ -1194,9 +1203,11 @@
|
| 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;
|
| + { TryAllocation t =
|
| + properties()->CopySize(properties()->length() + new_unused + 1);
|
| + if (!t->ToObject(&values)) return t;
|
| + }
|
| set_properties(FixedArray::cast(values));
|
| }
|
| set_map(new_map);
|
| @@ -1210,9 +1221,11 @@
|
| // Normalize the object if the name is an actual string (not the
|
| // hidden symbols) and is not a real identifier.
|
| StringInputBuffer buffer(name);
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) {
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| return AddSlowProperty(name, value, attributes);
|
| }
|
|
|
| @@ -1222,9 +1235,11 @@
|
|
|
| // 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;
|
| + { TryAllocation t =
|
| + old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);
|
| + if (!t->ToObject(&new_descriptors)) return t;
|
| + }
|
|
|
| // 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.
|
| @@ -1235,28 +1250,36 @@
|
| ASSERT(index < map()->inobject_properties() ||
|
| (index - map()->inobject_properties()) < properties()->length() ||
|
| map()->unused_property_fields() == 0);
|
| + Object* r;
|
| + { TryAllocation t = map()->CopyDropDescriptors();
|
| + if (!t->ToObject(&r)) return t;
|
| + }
|
| // Allocate a new map for the object.
|
| - Object* r = map()->CopyDropDescriptors();
|
| - if (r->IsFailure()) return r;
|
| Map* new_map = Map::cast(r);
|
| if (allow_map_transition) {
|
| // Allocate new instance descriptors for the old map with map transition.
|
| + Object* r;
|
| + { TryAllocation t = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
|
| + if (!t->ToObject(&r)) return t;
|
| + }
|
| MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
|
| - Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
|
| - if (r->IsFailure()) return r;
|
| old_descriptors = DescriptorArray::cast(r);
|
| }
|
|
|
| if (map()->unused_property_fields() == 0) {
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| if (properties()->length() > MaxFastProperties()) {
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return 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;
|
| + { TryAllocation t =
|
| + properties()->CopySize(properties()->length() + kFieldsAdded);
|
| + if (!t->ToObject(&values)) return t;
|
| + }
|
| set_properties(FixedArray::cast(values));
|
| new_map->set_unused_property_fields(kFieldsAdded - 1);
|
| } else {
|
| @@ -1278,13 +1301,17 @@
|
|
|
| // 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;
|
| + { TryAllocation t =
|
| + map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);
|
| + if (!t->ToObject(&new_descriptors)) return t;
|
| + }
|
|
|
| + Object* new_map;
|
| + { TryAllocation t = map()->CopyDropDescriptors();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| // Allocate a new map for the object.
|
| - Object* new_map = map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
|
|
| DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors);
|
| Map::cast(new_map)->set_instance_descriptors(descriptors);
|
| @@ -1341,14 +1368,17 @@
|
| dict->SetNextEnumerationIndex(index + 1);
|
| dict->SetEntry(entry, name, store_value, details);
|
| return value;
|
| + { TryAllocation t = Heap::AllocateJSGlobalPropertyCell(value);
|
| + if (!t->ToObject(&store_value)) return t;
|
| }
|
| - store_value = Heap::AllocateJSGlobalPropertyCell(value);
|
| - if (store_value->IsFailure()) return store_value;
|
| + }
|
| JSGlobalPropertyCell::cast(store_value)->set_value(value);
|
| }
|
| + Object* result;
|
| + { TryAllocation t = dict->Add(name, store_value, details);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| PropertyDetails details = PropertyDetails(attributes, NORMAL);
|
| - Object* result = dict->Add(name, store_value, details);
|
| - if (result->IsFailure()) return result;
|
| if (dict != result) set_properties(StringDictionary::cast(result));
|
| return value;
|
| }
|
| @@ -1376,9 +1406,11 @@
|
| }
|
| } else {
|
| // Normalize the object to prevent very large instance descriptors.
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // This eliminates unwanted N^2 allocation and lookup behavior.
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| }
|
| }
|
| return AddSlowProperty(name, value, attributes);
|
| @@ -1422,9 +1454,11 @@
|
| String* name,
|
| Object* new_value,
|
| PropertyAttributes attributes) {
|
| + Object* result;
|
| + { TryAllocation t = ConvertDescriptorToField(name, new_value, attributes);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| Map* old_map = map();
|
| - Object* result = ConvertDescriptorToField(name, new_value, attributes);
|
| - if (result->IsFailure()) return result;
|
| // If we get to this point we have succeeded - do not return failure
|
| // after this point. Later stuff is optional.
|
| if (!HasFastProperties()) {
|
| @@ -1451,24 +1485,30 @@
|
| Object* new_value,
|
| PropertyAttributes attributes) {
|
| if (map()->unused_property_fields() == 0 &&
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| properties()->length() > MaxFastProperties()) {
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return 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;
|
| + { TryAllocation t = map()->instance_descriptors()->
|
| + CopyInsert(&new_field, REMOVE_TRANSITIONS);
|
| + if (!t->ToObject(&descriptors_unchecked)) return t;
|
| + }
|
| DescriptorArray* new_descriptors =
|
| DescriptorArray::cast(descriptors_unchecked);
|
|
|
| + Object* new_map_unchecked;
|
| + { TryAllocation t = map()->CopyDropDescriptors();
|
| + if (!t->ToObject(&new_map_unchecked)) return t;
|
| + }
|
| // Make a new map for the object.
|
| - Object* new_map_unchecked = map()->CopyDropDescriptors();
|
| - if (new_map_unchecked->IsFailure()) return new_map_unchecked;
|
| Map* new_map = Map::cast(new_map_unchecked);
|
| new_map->set_instance_descriptors(new_descriptors);
|
|
|
| @@ -1477,9 +1517,11 @@
|
| 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;
|
| + Object* new_properties_unchecked;
|
| + { TryAllocation t =
|
| + properties()->CopySize(properties()->length() + kFieldsAdded);
|
| + if (!t->ToObject(&new_properties_unchecked)) return t;
|
| + }
|
| new_properties = FixedArray::cast(new_properties_unchecked);
|
| }
|
|
|
| @@ -2117,9 +2159,10 @@
|
| #endif
|
| return result;
|
| }
|
| + { TryAllocation t = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
|
|
| - result = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
|
| - if (result->IsFailure()) return result;
|
| set(index, result);
|
| Counters::normalized_maps.Increment();
|
|
|
| @@ -2176,9 +2219,11 @@
|
| // 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;
|
| + { TryAllocation t = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
|
| + UNIQUE_NORMALIZED_MAP);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| Counters::normalized_maps.Increment();
|
|
|
| set_map(Map::cast(obj));
|
| @@ -2201,9 +2246,11 @@
|
| } else {
|
| property_count += 2; // Make space for two more properties.
|
| }
|
| - Object* obj =
|
| - StringDictionary::Allocate(property_count);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* obj;
|
| + { TryAllocation t =
|
| + StringDictionary::Allocate(property_count);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| StringDictionary* dictionary = StringDictionary::cast(obj);
|
|
|
| DescriptorArray* descs = map()->instance_descriptors();
|
| @@ -2213,27 +2260,33 @@
|
| case CONSTANT_FUNCTION: {
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, details.index());
|
| + Object* result;
|
| + { TryAllocation t = dictionary->Add(descs->GetKey(i), value, d);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| Object* value = descs->GetConstantFunction(i);
|
| - Object* result = dictionary->Add(descs->GetKey(i), value, d);
|
| - if (result->IsFailure()) return result;
|
| dictionary = StringDictionary::cast(result);
|
| break;
|
| }
|
| case FIELD: {
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, details.index());
|
| + Object* result;
|
| + { TryAllocation t = dictionary->Add(descs->GetKey(i), value, d);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| Object* value = FastPropertyAt(descs->GetFieldIndex(i));
|
| - Object* result = dictionary->Add(descs->GetKey(i), value, d);
|
| - if (result->IsFailure()) return result;
|
| dictionary = StringDictionary::cast(result);
|
| break;
|
| }
|
| case CALLBACKS: {
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), CALLBACKS, details.index());
|
| + Object* result;
|
| + { TryAllocation t = dictionary->Add(descs->GetKey(i), value, d);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| Object* value = descs->GetCallbacksObject(i);
|
| - Object* result = dictionary->Add(descs->GetKey(i), value, d);
|
| - if (result->IsFailure()) return result;
|
| dictionary = StringDictionary::cast(result);
|
| break;
|
| }
|
| @@ -2251,9 +2304,10 @@
|
| 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;
|
| + { TryAllocation t = Top::context()->global_context()->
|
| + normalized_map_cache()->Get(this, mode);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| Map* new_map = Map::cast(obj);
|
|
|
| // We have now successfully allocated all the necessary objects.
|
| @@ -2294,9 +2348,11 @@
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
| if (HasDictionaryElements()) return this;
|
| ASSERT(map()->has_fast_elements());
|
| + Object* obj;
|
| + { TryAllocation t = map()->GetSlowElementsMap();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
|
|
| - Object* obj = map()->GetSlowElementsMap();
|
| - if (obj->IsFailure()) return obj;
|
| Map* new_map = Map::cast(obj);
|
|
|
| // Get number of entries.
|
| @@ -2305,17 +2361,20 @@
|
| // Compute the effective length.
|
| int length = IsJSArray() ?
|
| Smi::cast(JSArray::cast(this)->length())->value() :
|
| + { TryAllocation t = NumberDictionary::Allocate(length);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| array->length();
|
| - obj = NumberDictionary::Allocate(length);
|
| - if (obj->IsFailure()) return obj;
|
| NumberDictionary* dictionary = NumberDictionary::cast(obj);
|
| // Copy entries.
|
| for (int i = 0; i < length; i++) {
|
| Object* value = array->get(i);
|
| if (!value->IsTheHole()) {
|
| + Object* result;
|
| + { TryAllocation t = dictionary->AddNumberEntry(i, array->get(i), details);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| PropertyDetails details = PropertyDetails(NONE, NORMAL);
|
| - Object* result = dictionary->AddNumberEntry(i, array->get(i), details);
|
| - if (result->IsFailure()) return result;
|
| dictionary = NumberDictionary::cast(result);
|
| }
|
| }
|
| @@ -2344,9 +2403,11 @@
|
| LocalLookupRealNamedProperty(name, &result);
|
| if (!result.IsProperty()) return Heap::true_value();
|
|
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Normalize object if needed.
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| return DeleteNormalizedProperty(name, mode);
|
| }
|
| @@ -2386,9 +2447,11 @@
|
| DeleteMode mode) {
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
| switch (GetElementsKind()) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureWritableFastElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| case FAST_ELEMENTS: {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| uint32_t length = IsJSArray() ?
|
| static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
|
| static_cast<uint32_t>(FixedArray::cast(elements())->length());
|
| @@ -2468,9 +2531,11 @@
|
| }
|
|
|
| switch (GetElementsKind()) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureWritableFastElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| case FAST_ELEMENTS: {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| uint32_t length = IsJSArray() ?
|
| static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
|
| static_cast<uint32_t>(FixedArray::cast(elements())->length());
|
| @@ -2543,9 +2608,11 @@
|
| }
|
| return DeletePropertyWithInterceptor(name);
|
| }
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Normalize object if needed.
|
| - Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (obj->IsFailure()) return obj;
|
| // Make sure the properties are normalized before removing the entry.
|
| return DeleteNormalizedProperty(name, mode);
|
| }
|
| @@ -2653,17 +2720,21 @@
|
|
|
| Object* JSObject::PreventExtensions() {
|
| // If there are fast elements we normalize.
|
| + Object* ok;
|
| + { TryAllocation t = NormalizeElements();
|
| + if (!t->ToObject(&ok)) return t;
|
| + }
|
| if (HasFastElements()) {
|
| - Object* ok = NormalizeElements();
|
| - if (ok->IsFailure()) return 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
|
| + Object* new_map;
|
| + { TryAllocation t = map()->CopyDropTransitions();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| // be extensible.
|
| - Object* new_map = map()->CopyDropTransitions();
|
| - if (new_map->IsFailure()) return new_map;
|
| Map::cast(new_map)->set_is_extensible(false);
|
| set_map(Map::cast(new_map));
|
| ASSERT(!map()->is_extensible());
|
| @@ -2867,9 +2938,11 @@
|
| }
|
| }
|
|
|
| + Object* structure;
|
| + { TryAllocation t = Heap::AllocateFixedArray(2, TENURED);
|
| + if (!t->ToObject(&structure)) return t;
|
| + }
|
| // Allocate the fixed array to hold getter and setter.
|
| - Object* structure = Heap::AllocateFixedArray(2, TENURED);
|
| - if (structure->IsFailure()) return structure;
|
|
|
| if (is_element) {
|
| return SetElementCallback(index, structure, attributes);
|
| @@ -2908,14 +2981,18 @@
|
| PropertyAttributes attributes) {
|
| PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
|
|
|
| + Object* ok;
|
| + { TryAllocation t = NormalizeElements();
|
| + if (!t->ToObject(&ok)) return t;
|
| + }
|
| // Normalize elements to make this operation simple.
|
| - Object* ok = NormalizeElements();
|
| - if (ok->IsFailure()) return ok;
|
|
|
| // Update the dictionary with the new CALLBACKS property.
|
| - Object* dict =
|
| - element_dictionary()->Set(index, structure, details);
|
| - if (dict->IsFailure()) return dict;
|
| + Object* dict;
|
| + { TryAllocation t =
|
| + element_dictionary()->Set(index, structure, details);
|
| + if (!t->ToObject(&dict)) return t;
|
| + }
|
|
|
| NumberDictionary* elements = NumberDictionary::cast(dict);
|
| elements->set_requires_slow_elements();
|
| @@ -2935,25 +3012,32 @@
|
| (map()->instance_descriptors()->number_of_descriptors()
|
| < DescriptorArray::kMaxNumberOfDescriptors);
|
|
|
| + Object* ok;
|
| + { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| + if (!t->ToObject(&ok)) return t;
|
| + }
|
| // Normalize object to make this operation simple.
|
| - Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
|
| - if (ok->IsFailure()) return 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.
|
| + Object* new_map;
|
| + { TryAllocation t = map()->CopyDropDescriptors();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| if (IsGlobalObject()) {
|
| - Object* new_map = map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| set_map(Map::cast(new_map));
|
| }
|
|
|
| + Object* result;
|
| + { TryAllocation t = SetNormalizedProperty(name, structure, details);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| // Update the dictionary with the new CALLBACKS property.
|
| - Object* result = SetNormalizedProperty(name, structure, details);
|
| - if (result->IsFailure()) return result;
|
|
|
| + { TryAllocation t = TransformToFastProperties(0);
|
| + if (!t->ToObject(&ok)) return t;
|
| + }
|
| if (convert_back_to_fast) {
|
| - ok = TransformToFastProperties(0);
|
| - if (ok->IsFailure()) return ok;
|
| }
|
| return result;
|
| }
|
| @@ -3036,9 +3120,12 @@
|
| UNREACHABLE();
|
| break;
|
| }
|
| + Object* ok;
|
| + { TryAllocation t =
|
| + SetElementCallback(index, info, info->property_attributes());
|
| + if (!t->ToObject(&ok)) return t;
|
| + }
|
|
|
| - Object* ok = SetElementCallback(index, info, info->property_attributes());
|
| - if (ok->IsFailure()) return ok;
|
| } else {
|
| // Lookup the name.
|
| LookupResult result;
|
| @@ -3047,9 +3134,12 @@
|
| // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
|
| if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
|
| return Heap::undefined_value();
|
| + Object* ok;
|
| + { TryAllocation t =
|
| + SetPropertyCallback(name, info, info->property_attributes());
|
| + if (!t->ToObject(&ok)) return t;
|
| }
|
| - Object* ok = SetPropertyCallback(name, info, info->property_attributes());
|
| - if (ok->IsFailure()) return ok;
|
| + }
|
| }
|
|
|
| return this;
|
| @@ -3132,9 +3222,11 @@
|
| }
|
|
|
|
|
| + Object* result;
|
| + { TryAllocation t = Heap::AllocateMap(instance_type(), instance_size());
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| Object* Map::CopyDropDescriptors() {
|
| - Object* result = Heap::AllocateMap(instance_type(), instance_size());
|
| - if (result->IsFailure()) return result;
|
| Map::cast(result)->set_prototype(prototype());
|
| Map::cast(result)->set_constructor(constructor());
|
| // Don't copy descriptors, so map transitions always remain a forest.
|
| @@ -3152,9 +3244,11 @@
|
| 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;
|
| + { TryAllocation t =
|
| + ctor->initial_map()->instance_descriptors()->RemoveTransitions();
|
| + if (!t->ToObject(&descriptors)) return t;
|
| + }
|
| Map::cast(result)->set_instance_descriptors(
|
| DescriptorArray::cast(descriptors));
|
| Map::cast(result)->set_pre_allocated_property_fields(
|
| @@ -3174,9 +3268,11 @@
|
| if (mode == CLEAR_INOBJECT_PROPERTIES) {
|
| new_instance_size -= inobject_properties() * kPointerSize;
|
| }
|
| + Object* result;
|
| + { TryAllocation t = Heap::AllocateMap(instance_type(), new_instance_size);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
|
|
| - Object* result = Heap::AllocateMap(instance_type(), new_instance_size);
|
| - if (result->IsFailure()) return result;
|
|
|
| if (mode != CLEAR_INOBJECT_PROPERTIES) {
|
| Map::cast(result)->set_inobject_properties(inobject_properties());
|
| @@ -3200,11 +3296,15 @@
|
| }
|
|
|
|
|
| + Object* new_map;
|
| + { TryAllocation t = CopyDropDescriptors();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| Object* Map::CopyDropTransitions() {
|
| - Object* new_map = CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
| - Object* descriptors = instance_descriptors()->RemoveTransitions();
|
| - if (descriptors->IsFailure()) return descriptors;
|
| + Object* descriptors;
|
| + { TryAllocation t = instance_descriptors()->RemoveTransitions();
|
| + if (!t->ToObject(&descriptors)) return t;
|
| + }
|
| cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
|
| return new_map;
|
| }
|
| @@ -3212,9 +3312,11 @@
|
|
|
| Object* Map::UpdateCodeCache(String* name, Code* code) {
|
| // Allocate the code cache if not present.
|
| + Object* result;
|
| + { TryAllocation t = Heap::AllocateCodeCache();
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| if (code_cache()->IsFixedArray()) {
|
| - Object* result = Heap::AllocateCodeCache();
|
| - if (result->IsFailure()) return result;
|
| set_code_cache(result);
|
| }
|
|
|
| @@ -3300,9 +3402,11 @@
|
| 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;
|
| + { TryAllocation t =
|
| + CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| set_normal_type_cache(result);
|
| }
|
| return UpdateNormalTypeCache(name, code);
|
| @@ -3358,9 +3462,11 @@
|
| // multiple of the entry size.
|
| int new_length = length + ((length >> 1)) + kCodeCacheEntrySize;
|
| new_length = new_length - new_length % kCodeCacheEntrySize;
|
| + Object* result;
|
| + { TryAllocation t = cache->CopySize(new_length);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| ASSERT((new_length % kCodeCacheEntrySize) == 0);
|
| - Object* result = cache->CopySize(new_length);
|
| - if (result->IsFailure()) return result;
|
|
|
| // Add the (name, code) pair to the new cache.
|
| cache = FixedArray::cast(result);
|
| @@ -3373,9 +3479,11 @@
|
|
|
| Object* CodeCache::UpdateNormalTypeCache(String* name, Code* code) {
|
| // Adding a new entry can cause a new cache to be allocated.
|
| + Object* new_cache;
|
| + { TryAllocation t = cache->Put(name, code);
|
| + if (!t->ToObject(&new_cache)) return t;
|
| + }
|
| CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
|
| - Object* new_cache = cache->Put(name, code);
|
| - if (new_cache->IsFailure()) return new_cache;
|
| set_normal_type_cache(new_cache);
|
| return this;
|
| }
|
| @@ -3494,9 +3602,11 @@
|
| }
|
|
|
| Object* AsObject() {
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArray(2);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| ASSERT(code_ != NULL);
|
| - Object* obj = Heap::AllocateFixedArray(2);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray* pair = FixedArray::cast(obj);
|
| pair->set(0, name_);
|
| pair->set(1, code_);
|
| @@ -3519,16 +3629,20 @@
|
|
|
|
|
| Object* CodeCacheHashTable::Put(String* name, Code* code) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, &key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| CodeCacheHashTableKey key(name, code);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| // Don't use this, as the table might have grown.
|
| CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj);
|
|
|
| + Object* k;
|
| + { TryAllocation t = key.AsObject();
|
| + if (!t->ToObject(&k)) return t;
|
| + }
|
| int entry = cache->FindInsertionEntry(key.Hash());
|
| - Object* k = key.AsObject();
|
| - if (k->IsFailure()) return k;
|
|
|
| cache->set(EntryToIndex(entry), k);
|
| cache->set(EntryToIndex(entry) + 1, code);
|
| @@ -3575,9 +3689,11 @@
|
| NumberDictionary* dict = array->element_dictionary();
|
| int size = dict->NumberOfElements();
|
|
|
| + Object* object;
|
| + { TryAllocation t = Heap::AllocateFixedArray(size);
|
| + if (!t->ToObject(&object)) return t;
|
| + }
|
| // Allocate a temporary fixed array.
|
| - Object* object = Heap::AllocateFixedArray(size);
|
| - if (object->IsFailure()) return object;
|
| FixedArray* key_array = FixedArray::cast(object);
|
|
|
| int capacity = dict->Capacity();
|
| @@ -3615,9 +3731,11 @@
|
|
|
| if (extra == 0) return this;
|
|
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArray(len0 + extra);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Allocate the result
|
| - Object* obj = Heap::AllocateFixedArray(len0 + extra);
|
| - if (obj->IsFailure()) return obj;
|
| // Fill in the content
|
| AssertNoAllocation no_gc;
|
| FixedArray* result = FixedArray::cast(obj);
|
| @@ -3640,9 +3758,11 @@
|
|
|
|
|
| Object* FixedArray::CopySize(int new_length) {
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArray(new_length);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| if (new_length == 0) return Heap::empty_fixed_array();
|
| - Object* obj = Heap::AllocateFixedArray(new_length);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray* result = FixedArray::cast(obj);
|
| // Copy the content
|
| AssertNoAllocation no_gc;
|
| @@ -3682,15 +3802,18 @@
|
| 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;
|
| + { TryAllocation t =
|
| + Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors));
|
| + if (!t->ToObject(&array)) return t;
|
| + }
|
| // Do not use DescriptorArray::cast on incomplete object.
|
| FixedArray* result = FixedArray::cast(array);
|
|
|
| + { TryAllocation t = Heap::AllocateFixedArray(number_of_descriptors << 1);
|
| + if (!t->ToObject(&array)) return t;
|
| + }
|
| // Allocate the content array and set it in the descriptor array.
|
| - array = Heap::AllocateFixedArray(number_of_descriptors << 1);
|
| - if (array->IsFailure()) return array;
|
| result->set(kContentArrayIndex, array);
|
| result->set(kEnumerationIndexIndex,
|
| Smi::FromInt(PropertyDetails::kInitialIndex));
|
| @@ -3727,9 +3850,11 @@
|
| ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition());
|
| ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR);
|
|
|
| + Object* result;
|
| + { TryAllocation t = descriptor->KeyToSymbol();
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| // Ensure the key is a symbol.
|
| - Object* result = descriptor->KeyToSymbol();
|
| - if (result->IsFailure()) return result;
|
|
|
| int transitions = 0;
|
| int null_descriptors = 0;
|
| @@ -3768,9 +3893,10 @@
|
| // a transition that will be replaced. Adjust count in this case.
|
| ++new_size;
|
| }
|
| + { TryAllocation t = Allocate(new_size);
|
| + if (!t->ToObject(&result)) return t;
|
| }
|
| - result = Allocate(new_size);
|
| - if (result->IsFailure()) return result;
|
| + }
|
| DescriptorArray* new_descriptors = DescriptorArray::cast(result);
|
| // Set the enumeration index in the descriptors and set the enumeration index
|
| // in the result.
|
| @@ -3829,9 +3955,11 @@
|
| if (!IsProperty(i)) num_removed++;
|
| }
|
|
|
| + Object* result;
|
| + { TryAllocation t = Allocate(number_of_descriptors() - num_removed);
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| // Allocate the new descriptor array.
|
| - Object* result = Allocate(number_of_descriptors() - num_removed);
|
| - if (result->IsFailure()) return result;
|
| DescriptorArray* new_descriptors = DescriptorArray::cast(result);
|
|
|
| // Copy the content.
|
| @@ -5183,9 +5311,11 @@
|
| if (!value->IsJSObject()) {
|
| // Copy the map so this does not affect unrelated functions.
|
| // Remove map transitions because they point to maps with a
|
| + Object* new_map;
|
| + { TryAllocation t = map()->CopyDropTransitions();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| // different prototype.
|
| - Object* new_map = map()->CopyDropTransitions();
|
| - if (new_map->IsFailure()) return new_map;
|
| set_map(Map::cast(new_map));
|
| map()->set_constructor(value);
|
| map()->set_non_instance_prototype(true);
|
| @@ -5218,9 +5348,11 @@
|
| }
|
|
|
|
|
| + Object* symbol;
|
| + { TryAllocation t = Heap::LookupAsciiSymbol(to_string);
|
| + if (!t->ToObject(&symbol)) return t;
|
| + }
|
| Object* Oddball::Initialize(const char* to_string, Object* to_number) {
|
| - Object* symbol = Heap::LookupAsciiSymbol(to_string);
|
| - if (symbol->IsFailure()) return symbol;
|
| set_to_string(String::cast(symbol));
|
| set_to_number(to_number);
|
| return this;
|
| @@ -5705,13 +5837,16 @@
|
| Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) {
|
| // We should never end in here with a pixel or external array.
|
| ASSERT(!HasPixelElements() && !HasExternalArrayElements());
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArrayWithHoles(capacity);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
|
|
| - Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray* elems = FixedArray::cast(obj);
|
| + { TryAllocation t = map()->GetFastElementsMap();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
|
|
| - obj = map()->GetFastElementsMap();
|
| - if (obj->IsFailure()) return obj;
|
| Map* new_map = Map::cast(obj);
|
|
|
| AssertNoAllocation no_gc;
|
| @@ -5763,9 +5898,11 @@
|
| case FAST_ELEMENTS: {
|
| // Make sure we never try to shrink dense arrays into sparse arrays.
|
| ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <=
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| new_length);
|
| - Object* obj = NormalizeElements();
|
| - if (obj->IsFailure()) return obj;
|
|
|
| // Update length for JSArrays.
|
| if (IsJSArray()) JSArray::cast(this)->set_length(len);
|
| @@ -5794,9 +5931,11 @@
|
| FixedArray* new_elements;
|
| if (capacity == 0) {
|
| new_elements = Heap::empty_fixed_array();
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArrayWithHoles(capacity);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| } else {
|
| - Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
|
| - if (obj->IsFailure()) return obj;
|
| new_elements = FixedArray::cast(obj);
|
| }
|
| set_elements(new_elements);
|
| @@ -5842,9 +5981,11 @@
|
| case FAST_ELEMENTS: {
|
| int old_capacity = FixedArray::cast(elements())->length();
|
| if (value <= old_capacity) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureWritableFastElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| if (IsJSArray()) {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return 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
|
| @@ -5859,9 +6000,12 @@
|
| int min = NewElementsCapacity(old_capacity);
|
| int new_capacity = value > min ? value : min;
|
| if (new_capacity <= kMaxFastElementsLength ||
|
| + Object* obj;
|
| + { TryAllocation t =
|
| + SetFastElementsCapacityAndLength(new_capacity, value);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| !ShouldConvertToSlowElements(new_capacity)) {
|
| - Object* obj = SetFastElementsCapacityAndLength(new_capacity, value);
|
| - if (obj->IsFailure()) return obj;
|
| return this;
|
| }
|
| break;
|
| @@ -5871,9 +6015,11 @@
|
| if (value == 0) {
|
| // If the length of a slow array is reset to zero, we clear
|
| // the array and flush backing storage. This has the added
|
| + Object* obj;
|
| + { TryAllocation t = ResetElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // benefit that the array returns to fast mode.
|
| - Object* obj = ResetElements();
|
| - if (obj->IsFailure()) return obj;
|
| } else {
|
| // Remove deleted elements.
|
| uint32_t old_length =
|
| @@ -5901,9 +6047,11 @@
|
| }
|
|
|
| // len is not a number so make the array size one and
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArray(1);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // set only element to len.
|
| - Object* obj = Heap::AllocateFixedArray(1);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray::cast(obj)->set(0, len);
|
| if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
|
| set_elements(FixedArray::cast(obj));
|
| @@ -5943,9 +6091,11 @@
|
| }
|
| }
|
|
|
| + Object* new_map;
|
| + { TryAllocation t = real_receiver->map()->CopyDropTransitions();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| // Set the new prototype of the object.
|
| - Object* new_map = real_receiver->map()->CopyDropTransitions();
|
| - if (new_map->IsFailure()) return new_map;
|
| Map::cast(new_map)->set_prototype(value);
|
| real_receiver->set_map(Map::cast(new_map));
|
|
|
| @@ -6315,9 +6465,11 @@
|
| // elements.
|
| Object* JSObject::SetFastElement(uint32_t index, Object* value) {
|
| ASSERT(HasFastElements());
|
| + Object* elms_obj;
|
| + { TryAllocation t = EnsureWritableFastElements();
|
| + if (!t->ToObject(&elms_obj)) return t;
|
| + }
|
|
|
| - Object* elms_obj = EnsureWritableFastElements();
|
| - if (elms_obj->IsFailure()) return elms_obj;
|
| FixedArray* elms = FixedArray::cast(elms_obj);
|
| uint32_t elms_length = static_cast<uint32_t>(elms->length());
|
|
|
| @@ -6347,17 +6499,22 @@
|
| int new_capacity = NewElementsCapacity(index+1);
|
| if (new_capacity <= kMaxFastElementsLength ||
|
| !ShouldConvertToSlowElements(new_capacity)) {
|
| + Object* obj;
|
| + { TryAllocation t =
|
| + SetFastElementsCapacityAndLength(new_capacity, index + 1);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| ASSERT(static_cast<uint32_t>(new_capacity) > index);
|
| - Object* obj = SetFastElementsCapacityAndLength(new_capacity, index + 1);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray::cast(elements())->set(index, value);
|
| return value;
|
| }
|
| }
|
|
|
| + Object* obj;
|
| + { TryAllocation t = NormalizeElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Otherwise default to slow case.
|
| - Object* obj = NormalizeElements();
|
| - if (obj->IsFailure()) return obj;
|
| ASSERT(HasDictionaryElements());
|
| return SetElement(index, value);
|
| }
|
| @@ -6459,9 +6616,11 @@
|
| Handle<Object> args[1] = { index_string };
|
| return Top::Throw(*Factory::NewTypeError("object_not_extensible",
|
| HandleVector(args, 1)));
|
| + Object* result;
|
| + { TryAllocation t = dictionary->AtNumberPut(index, value);
|
| + if (!t->ToObject(&result)) return t;
|
| }
|
| - Object* result = dictionary->AtNumberPut(index, value);
|
| - if (result->IsFailure()) return result;
|
| + }
|
| if (elms != FixedArray::cast(result)) {
|
| set_elements(FixedArray::cast(result));
|
| }
|
| @@ -6470,9 +6629,11 @@
|
| // 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;
|
| + { TryAllocation t = array->JSArrayUpdateLengthFromIndex(index,
|
| + value);
|
| + if (!t->ToObject(&return_value)) return t;
|
| + }
|
| }
|
|
|
| // Attempt to put this object back in fast case.
|
| @@ -6482,9 +6643,12 @@
|
| CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
|
| } else {
|
| new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
|
| + Object* obj;
|
| + { TryAllocation t =
|
| + SetFastElementsCapacityAndLength(new_length, new_length);
|
| + if (!t->ToObject(&obj)) return t;
|
| }
|
| - Object* obj = SetFastElementsCapacityAndLength(new_length, new_length);
|
| - if (obj->IsFailure()) return obj;
|
| + }
|
| #ifdef DEBUG
|
| if (FLAG_trace_normalization) {
|
| PrintF("Object elements are fast case again:\n");
|
| @@ -6512,9 +6676,11 @@
|
| // 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;
|
| + { TryAllocation t =
|
| + Heap::NumberFromDouble(static_cast<double>(index) + 1);
|
| + if (!t->ToObject(&len)) return t;
|
| + }
|
| set_length(len);
|
| }
|
| return value;
|
| @@ -7374,9 +7540,11 @@
|
| return StringSharedHashHelper(source, shared);
|
| }
|
|
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArray(2);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| Object* AsObject() {
|
| - Object* obj = Heap::AllocateFixedArray(2);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray* pair = FixedArray::cast(obj);
|
| pair->set(0, shared_);
|
| pair->set(1, source_);
|
| @@ -7613,9 +7781,11 @@
|
|
|
| const int kMinCapacityForPretenure = 256;
|
| bool pretenure =
|
| + Object* obj;
|
| + { TryAllocation t = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this);
|
| - Object* obj = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| AssertNoAllocation no_gc;
|
| HashTable* table = HashTable::cast(obj);
|
| @@ -7749,14 +7919,18 @@
|
| NumberDictionary* dict = element_dictionary();
|
| HeapNumber* result_double = NULL;
|
| if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
|
| + Object* new_double;
|
| + { TryAllocation t = Heap::AllocateHeapNumber(0.0);
|
| + if (!t->ToObject(&new_double)) return t;
|
| + }
|
| // Allocate space for result before we start mutating the object.
|
| - Object* new_double = Heap::AllocateHeapNumber(0.0);
|
| - if (new_double->IsFailure()) return new_double;
|
| result_double = HeapNumber::cast(new_double);
|
| }
|
| + Object* obj;
|
| + { TryAllocation t = NumberDictionary::Allocate(dict->NumberOfElements());
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
|
|
| - Object* obj = NumberDictionary::Allocate(dict->NumberOfElements());
|
| - if (obj->IsFailure()) return obj;
|
| NumberDictionary* new_dict = NumberDictionary::cast(obj);
|
|
|
| AssertNoAllocation no_alloc;
|
| @@ -7827,23 +8001,29 @@
|
| return PrepareSlowElementsForSort(limit);
|
| }
|
| // Convert to fast elements.
|
| + Object* obj;
|
| + { TryAllocation t = map()->GetFastElementsMap();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
|
|
| - Object* obj = map()->GetFastElementsMap();
|
| - if (obj->IsFailure()) return 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;
|
| + { TryAllocation t =
|
| + Heap::AllocateFixedArray(dict->NumberOfElements(), tenure);
|
| + if (!t->ToObject(&new_array)) return t;
|
| + }
|
| FixedArray* fast_elements = FixedArray::cast(new_array);
|
| dict->CopyValuesTo(fast_elements);
|
|
|
| set_map(new_map);
|
| set_elements(fast_elements);
|
| + Object* obj;
|
| + { TryAllocation t = EnsureWritableFastElements();
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| } else {
|
| - Object* obj = EnsureWritableFastElements();
|
| - if (obj->IsFailure()) return obj;
|
| }
|
| ASSERT(HasFastElements());
|
|
|
| @@ -7862,9 +8042,11 @@
|
| HeapNumber* result_double = NULL;
|
| if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
|
| // Pessimistically allocate space for return value before
|
| + Object* new_double;
|
| + { TryAllocation t = Heap::AllocateHeapNumber(0.0);
|
| + if (!t->ToObject(&new_double)) return t;
|
| + }
|
| // we start mutating the array.
|
| - Object* new_double = Heap::AllocateHeapNumber(0.0);
|
| - if (new_double->IsFailure()) return new_double;
|
| result_double = HeapNumber::cast(new_double);
|
| }
|
|
|
| @@ -8059,13 +8241,18 @@
|
| Object* GlobalObject::EnsurePropertyCell(String* name) {
|
| ASSERT(!HasFastProperties());
|
| int entry = property_dictionary()->FindEntry(name);
|
| + Object* cell;
|
| + { TryAllocation t =
|
| + Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value());
|
| + if (!t->ToObject(&cell)) return t;
|
| + }
|
| if (entry == StringDictionary::kNotFound) {
|
| - Object* cell = Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value());
|
| - if (cell->IsFailure()) return cell;
|
| PropertyDetails details(NONE, NORMAL);
|
| + Object* dictionary;
|
| + { TryAllocation t = property_dictionary()->Add(name, cell, details);
|
| + if (!t->ToObject(&dictionary)) return t;
|
| + }
|
| details = details.AsDeleted();
|
| - Object* dictionary = property_dictionary()->Add(name, cell, details);
|
| - if (dictionary->IsFailure()) return dictionary;
|
| set_properties(StringDictionary::cast(dictionary));
|
| return cell;
|
| } else {
|
| @@ -8188,13 +8375,17 @@
|
| return this;
|
| }
|
|
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Adding new symbol. Grow table if needed.
|
| - Object* obj = EnsureCapacity(1, key);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| + Object* symbol;
|
| + { TryAllocation t = key->AsObject();
|
| + if (!t->ToObject(&symbol)) return t;
|
| + }
|
| // Create symbol object.
|
| - Object* symbol = key->AsObject();
|
| - if (symbol->IsFailure()) return symbol;
|
|
|
| // If the symbol table grew as part of EnsureCapacity, obj is not
|
| // the current symbol table and therefore we cannot use
|
| @@ -8236,9 +8427,11 @@
|
|
|
|
|
| Object* CompilationCacheTable::Put(String* src, Object* value) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, &key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| StringKey key(src);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| CompilationCacheTable* cache =
|
| reinterpret_cast<CompilationCacheTable*>(obj);
|
| @@ -8253,16 +8446,20 @@
|
| Object* CompilationCacheTable::PutEval(String* src,
|
| Context* context,
|
| Object* value) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, &key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| StringSharedKey key(src, context->closure()->shared());
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| CompilationCacheTable* cache =
|
| reinterpret_cast<CompilationCacheTable*>(obj);
|
| int entry = cache->FindInsertionEntry(key.Hash());
|
| + Object* k;
|
| + { TryAllocation t = key.AsObject();
|
| + if (!t->ToObject(&k)) return t;
|
| + }
|
|
|
| - Object* k = key.AsObject();
|
| - if (k->IsFailure()) return k;
|
|
|
| cache->set(EntryToIndex(entry), k);
|
| cache->set(EntryToIndex(entry) + 1, value);
|
| @@ -8274,9 +8471,11 @@
|
| Object* CompilationCacheTable::PutRegExp(String* src,
|
| JSRegExp::Flags flags,
|
| FixedArray* value) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, &key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| RegExpKey key(src, flags);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| CompilationCacheTable* cache =
|
| reinterpret_cast<CompilationCacheTable*>(obj);
|
| @@ -8333,9 +8532,11 @@
|
|
|
|
|
| Object* MapCache::Put(FixedArray* array, Map* value) {
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, &key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| SymbolsKey key(array);
|
| - Object* obj = EnsureCapacity(1, &key);
|
| - if (obj->IsFailure()) return obj;
|
|
|
| MapCache* cache = reinterpret_cast<MapCache*>(obj);
|
| int entry = cache->FindInsertionEntry(key.Hash());
|
| @@ -8362,17 +8563,20 @@
|
| Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
|
| int length = HashTable<Shape, Key>::NumberOfElements();
|
|
|
| + Object* obj;
|
| + { TryAllocation t = Heap::AllocateFixedArray(length);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Allocate and initialize iteration order array.
|
| - Object* obj = Heap::AllocateFixedArray(length);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray* iteration_order = FixedArray::cast(obj);
|
| for (int i = 0; i < length; i++) {
|
| iteration_order->set(i, Smi::FromInt(i));
|
| }
|
|
|
| + { TryAllocation t = Heap::AllocateFixedArray(length);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Allocate array with enumeration order.
|
| - obj = Heap::AllocateFixedArray(length);
|
| - if (obj->IsFailure()) return obj;
|
| FixedArray* enumeration_order = FixedArray::cast(obj);
|
|
|
| // Fill the enumeration order array with property details.
|
| @@ -8417,9 +8621,11 @@
|
| // Check whether there are enough enumeration indices to add n elements.
|
| if (Shape::kIsEnumerable &&
|
| !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) {
|
| + Object* result;
|
| + { TryAllocation t = GenerateNewEnumerationIndices();
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| // If not, we generate new indices for the properties.
|
| - Object* result = GenerateNewEnumerationIndices();
|
| - if (result->IsFailure()) return result;
|
| }
|
| return HashTable<Shape, Key>::EnsureCapacity(n, key);
|
| }
|
| @@ -8472,12 +8678,16 @@
|
| return this;
|
| }
|
|
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Check whether the dictionary should be extended.
|
| - Object* obj = EnsureCapacity(1, key);
|
| - if (obj->IsFailure()) return obj;
|
| + Object* k;
|
| + { TryAllocation t = Shape::AsObject(key);
|
| + if (!t->ToObject(&k)) return t;
|
| + }
|
|
|
| - Object* k = Shape::AsObject(key);
|
| - if (k->IsFailure()) return k;
|
| PropertyDetails details = PropertyDetails(NONE, NORMAL);
|
| return Dictionary<Shape, Key>::cast(obj)->
|
| AddEntry(key, value, details, Shape::Hash(key));
|
| @@ -8490,9 +8700,11 @@
|
| PropertyDetails details) {
|
| // Valdate key is absent.
|
| SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound));
|
| + Object* obj;
|
| + { TryAllocation t = EnsureCapacity(1, key);
|
| + if (!t->ToObject(&obj)) return t;
|
| + }
|
| // Check whether the dictionary should be extended.
|
| - Object* obj = EnsureCapacity(1, key);
|
| - if (obj->IsFailure()) return obj;
|
| return Dictionary<Shape, Key>::cast(obj)->
|
| AddEntry(key, value, details, Shape::Hash(key));
|
| }
|
| @@ -8504,9 +8716,11 @@
|
| Object* value,
|
| PropertyDetails details,
|
| uint32_t hash) {
|
| + Object* k;
|
| + { TryAllocation t = Shape::AsObject(key);
|
| + if (!t->ToObject(&k)) return t;
|
| + }
|
| // Compute the key object.
|
| - Object* k = Shape::AsObject(key);
|
| - if (k->IsFailure()) return k;
|
|
|
| uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash);
|
| // Insert element at empty or deleted entry
|
| @@ -8686,9 +8900,11 @@
|
| NextEnumerationIndex() +
|
| (DescriptorArray::kMaxNumberOfDescriptors -
|
| NumberOfElements());
|
| + Object* result;
|
| + { TryAllocation t = GenerateNewEnumerationIndices();
|
| + if (!t->ToObject(&result)) return t;
|
| + }
|
| if (!PropertyDetails::IsValidIndex(max_enumeration_index)) {
|
| - Object* result = GenerateNewEnumerationIndices();
|
| - if (result->IsFailure()) return result;
|
| }
|
|
|
| int instance_descriptor_length = 0;
|
| @@ -8711,18 +8927,22 @@
|
| }
|
|
|
| // Allocate the instance descriptor.
|
| - Object* descriptors_unchecked =
|
| - DescriptorArray::Allocate(instance_descriptor_length);
|
| - if (descriptors_unchecked->IsFailure()) return descriptors_unchecked;
|
| + Object* descriptors_unchecked;
|
| + { TryAllocation t =
|
| + DescriptorArray::Allocate(instance_descriptor_length);
|
| + if (!t->ToObject(&descriptors_unchecked)) return t;
|
| + }
|
| DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked);
|
|
|
| int inobject_props = obj->map()->inobject_properties();
|
| int number_of_allocated_fields =
|
| number_of_fields + unused_property_fields - inobject_props;
|
|
|
| + Object* fields;
|
| + { TryAllocation t = Heap::AllocateFixedArray(number_of_allocated_fields);
|
| + if (!t->ToObject(&fields)) return t;
|
| + }
|
| // Allocate the fixed array for the fields.
|
| - Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields);
|
| - if (fields->IsFailure()) return fields;
|
|
|
| // Fill in the instance descriptor and the fields.
|
| int next_descriptor = 0;
|
| @@ -8731,9 +8951,11 @@
|
| Object* k = KeyAt(i);
|
| if (IsKey(k)) {
|
| Object* value = ValueAt(i);
|
| + Object* key;
|
| + { TryAllocation t = Heap::LookupSymbol(String::cast(k));
|
| + if (!t->ToObject(&key)) return t;
|
| + }
|
| // Ensure the key is a symbol before writing into the instance descriptor.
|
| - Object* key = Heap::LookupSymbol(String::cast(k));
|
| - if (key->IsFailure()) return key;
|
| PropertyDetails details = DetailsAt(i);
|
| PropertyType type = details.type();
|
|
|
| @@ -8771,9 +8993,11 @@
|
| ASSERT(current_offset == number_of_fields);
|
|
|
| descriptors->Sort();
|
| + Object* new_map;
|
| + { TryAllocation t = obj->map()->CopyDropDescriptors();
|
| + if (!t->ToObject(&new_map)) return t;
|
| + }
|
| // Allocate new map.
|
| - Object* new_map = obj->map()->CopyDropDescriptors();
|
| - if (new_map->IsFailure()) return new_map;
|
|
|
| // Transform the object.
|
| obj->set_map(Map::cast(new_map));
|
|
|