Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/objects.cc

Issue 3522008: This is a little experiment to move Failure to a superclass above Object... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 namespace v8 { 48 namespace v8 {
49 namespace internal { 49 namespace internal {
50 50
51 // Getters and setters are stored in a fixed array property. These are 51 // Getters and setters are stored in a fixed array property. These are
52 // constants for their indices. 52 // constants for their indices.
53 const int kGetterIndex = 0; 53 const int kGetterIndex = 0;
54 const int kSetterIndex = 1; 54 const int kSetterIndex = 1;
55 55
56 56
57 MUST_USE_RESULT static Object* CreateJSValue(JSFunction* constructor, 57 MUST_USE_RESULT static Object* CreateJSValue(JSFunction* constructor,
58 Object* result;
59 { TryAllocation t = Heap::AllocateJSObject(constructor);
60 if (!t->ToObject(&result)) return t;
61 }
58 Object* value) { 62 Object* value) {
59 Object* result = Heap::AllocateJSObject(constructor);
60 if (result->IsFailure()) return result;
61 JSValue::cast(result)->set_value(value); 63 JSValue::cast(result)->set_value(value);
62 return result; 64 return result;
63 } 65 }
64 66
65 67
66 Object* Object::ToObject(Context* global_context) { 68 Object* Object::ToObject(Context* global_context) {
67 if (IsNumber()) { 69 if (IsNumber()) {
68 return CreateJSValue(global_context->number_function(), this); 70 return CreateJSValue(global_context->number_function(), this);
69 } else if (IsBoolean()) { 71 } else if (IsBoolean()) {
70 return CreateJSValue(global_context->boolean_function(), this); 72 return CreateJSValue(global_context->boolean_function(), this);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 } 367 }
366 368
367 369
368 Object* JSObject::SetNormalizedProperty(String* name, 370 Object* JSObject::SetNormalizedProperty(String* name,
369 Object* value, 371 Object* value,
370 PropertyDetails details) { 372 PropertyDetails details) {
371 ASSERT(!HasFastProperties()); 373 ASSERT(!HasFastProperties());
372 int entry = property_dictionary()->FindEntry(name); 374 int entry = property_dictionary()->FindEntry(name);
373 if (entry == StringDictionary::kNotFound) { 375 if (entry == StringDictionary::kNotFound) {
374 Object* store_value = value; 376 Object* store_value = value;
377 { TryAllocation t = Heap::AllocateJSGlobalPropertyCell(value);
378 if (!t->ToObject(&store_value)) return t;
379 }
375 if (IsGlobalObject()) { 380 if (IsGlobalObject()) {
376 store_value = Heap::AllocateJSGlobalPropertyCell(value); 381 Object* dict;
377 if (store_value->IsFailure()) return store_value; 382 { TryAllocation t = property_dictionary()->Add(name, store_value, details);
383 if (!t->ToObject(&dict)) return t;
378 } 384 }
379 Object* dict = property_dictionary()->Add(name, store_value, details); 385 }
380 if (dict->IsFailure()) return dict;
381 set_properties(StringDictionary::cast(dict)); 386 set_properties(StringDictionary::cast(dict));
382 return value; 387 return value;
383 } 388 }
384 // Preserve enumeration index. 389 // Preserve enumeration index.
385 details = PropertyDetails(details.attributes(), 390 details = PropertyDetails(details.attributes(),
386 details.type(), 391 details.type(),
387 property_dictionary()->DetailsAt(entry).index()); 392 property_dictionary()->DetailsAt(entry).index());
388 if (IsGlobalObject()) { 393 if (IsGlobalObject()) {
389 JSGlobalPropertyCell* cell = 394 JSGlobalPropertyCell* cell =
390 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); 395 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry));
(...skipping 13 matching lines...) Expand all
404 int entry = dictionary->FindEntry(name); 409 int entry = dictionary->FindEntry(name);
405 if (entry != StringDictionary::kNotFound) { 410 if (entry != StringDictionary::kNotFound) {
406 // If we have a global object set the cell to the hole. 411 // If we have a global object set the cell to the hole.
407 if (IsGlobalObject()) { 412 if (IsGlobalObject()) {
408 PropertyDetails details = dictionary->DetailsAt(entry); 413 PropertyDetails details = dictionary->DetailsAt(entry);
409 if (details.IsDontDelete()) { 414 if (details.IsDontDelete()) {
410 if (mode != FORCE_DELETION) return Heap::false_value(); 415 if (mode != FORCE_DELETION) return Heap::false_value();
411 // When forced to delete global properties, we have to make a 416 // When forced to delete global properties, we have to make a
412 // map change to invalidate any ICs that think they can load 417 // map change to invalidate any ICs that think they can load
413 // from the DontDelete cell without checking if it contains 418 // from the DontDelete cell without checking if it contains
419 Object* new_map;
420 { TryAllocation t = map()->CopyDropDescriptors();
421 if (!t->ToObject(&new_map)) return t;
422 }
414 // the hole value. 423 // the hole value.
415 Object* new_map = map()->CopyDropDescriptors();
416 if (new_map->IsFailure()) return new_map;
417 set_map(Map::cast(new_map)); 424 set_map(Map::cast(new_map));
418 } 425 }
419 JSGlobalPropertyCell* cell = 426 JSGlobalPropertyCell* cell =
420 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); 427 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry));
421 cell->set_value(Heap::the_hole_value()); 428 cell->set_value(Heap::the_hole_value());
422 dictionary->DetailsAtPut(entry, details.AsDeleted()); 429 dictionary->DetailsAtPut(entry, details.AsDeleted());
423 } else { 430 } else {
424 return dictionary->DeleteProperty(entry, mode); 431 return dictionary->DeleteProperty(entry, mode);
425 } 432 }
426 } 433 }
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 if (cs->second()->length() == 0) { 642 if (cs->second()->length() == 0) {
636 return cs->first(); 643 return cs->first();
637 } 644 }
638 // There's little point in putting the flat string in new space if the 645 // There's little point in putting the flat string in new space if the
639 // cons string is in old space. It can never get GCed until there is 646 // cons string is in old space. It can never get GCed until there is
640 // an old space GC. 647 // an old space GC.
641 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; 648 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED;
642 int len = length(); 649 int len = length();
643 Object* object; 650 Object* object;
644 String* result; 651 String* result;
652 { TryAllocation t = Heap::AllocateRawAsciiString(len, tenure);
653 if (!t->ToObject(&object)) return t;
654 }
645 if (IsAsciiRepresentation()) { 655 if (IsAsciiRepresentation()) {
646 object = Heap::AllocateRawAsciiString(len, tenure);
647 if (object->IsFailure()) return object;
648 result = String::cast(object); 656 result = String::cast(object);
649 String* first = cs->first(); 657 String* first = cs->first();
650 int first_length = first->length(); 658 int first_length = first->length();
651 char* dest = SeqAsciiString::cast(result)->GetChars(); 659 char* dest = SeqAsciiString::cast(result)->GetChars();
652 WriteToFlat(first, dest, 0, first_length); 660 WriteToFlat(first, dest, 0, first_length);
653 String* second = cs->second(); 661 String* second = cs->second();
654 WriteToFlat(second, 662 WriteToFlat(second,
655 dest + first_length, 663 dest + first_length,
656 0, 664 0,
657 len - first_length); 665 len - first_length);
666 { TryAllocation t = Heap::AllocateRawTwoByteString(len, tenure);
667 if (!t->ToObject(&object)) return t;
668 }
658 } else { 669 } else {
659 object = Heap::AllocateRawTwoByteString(len, tenure);
660 if (object->IsFailure()) return object;
661 result = String::cast(object); 670 result = String::cast(object);
662 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); 671 uc16* dest = SeqTwoByteString::cast(result)->GetChars();
663 String* first = cs->first(); 672 String* first = cs->first();
664 int first_length = first->length(); 673 int first_length = first->length();
665 WriteToFlat(first, dest, 0, first_length); 674 WriteToFlat(first, dest, 0, first_length);
666 String* second = cs->second(); 675 String* second = cs->second();
667 WriteToFlat(second, 676 WriteToFlat(second,
668 dest + first_length, 677 dest + first_length,
669 0, 678 0,
670 len - first_length); 679 len - first_length);
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 } 1196 }
1188 1197
1189 1198
1190 Object* JSObject::AddFastPropertyUsingMap(Map* new_map, 1199 Object* JSObject::AddFastPropertyUsingMap(Map* new_map,
1191 String* name, 1200 String* name,
1192 Object* value) { 1201 Object* value) {
1193 int index = new_map->PropertyIndexFor(name); 1202 int index = new_map->PropertyIndexFor(name);
1194 if (map()->unused_property_fields() == 0) { 1203 if (map()->unused_property_fields() == 0) {
1195 ASSERT(map()->unused_property_fields() == 0); 1204 ASSERT(map()->unused_property_fields() == 0);
1196 int new_unused = new_map->unused_property_fields(); 1205 int new_unused = new_map->unused_property_fields();
1197 Object* values = 1206 Object* values;
1198 properties()->CopySize(properties()->length() + new_unused + 1); 1207 { TryAllocation t =
1199 if (values->IsFailure()) return values; 1208 properties()->CopySize(properties()->length() + new_unused + 1);
1209 if (!t->ToObject(&values)) return t;
1210 }
1200 set_properties(FixedArray::cast(values)); 1211 set_properties(FixedArray::cast(values));
1201 } 1212 }
1202 set_map(new_map); 1213 set_map(new_map);
1203 return FastPropertyAtPut(index, value); 1214 return FastPropertyAtPut(index, value);
1204 } 1215 }
1205 1216
1206 1217
1207 Object* JSObject::AddFastProperty(String* name, 1218 Object* JSObject::AddFastProperty(String* name,
1208 Object* value, 1219 Object* value,
1209 PropertyAttributes attributes) { 1220 PropertyAttributes attributes) {
1210 // Normalize the object if the name is an actual string (not the 1221 // Normalize the object if the name is an actual string (not the
1211 // hidden symbols) and is not a real identifier. 1222 // hidden symbols) and is not a real identifier.
1212 StringInputBuffer buffer(name); 1223 StringInputBuffer buffer(name);
1224 Object* obj;
1225 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1226 if (!t->ToObject(&obj)) return t;
1227 }
1213 if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) { 1228 if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) {
1214 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1215 if (obj->IsFailure()) return obj;
1216 return AddSlowProperty(name, value, attributes); 1229 return AddSlowProperty(name, value, attributes);
1217 } 1230 }
1218 1231
1219 DescriptorArray* old_descriptors = map()->instance_descriptors(); 1232 DescriptorArray* old_descriptors = map()->instance_descriptors();
1220 // Compute the new index for new field. 1233 // Compute the new index for new field.
1221 int index = map()->NextFreePropertyIndex(); 1234 int index = map()->NextFreePropertyIndex();
1222 1235
1223 // Allocate new instance descriptors with (name, index) added 1236 // Allocate new instance descriptors with (name, index) added
1224 FieldDescriptor new_field(name, index, attributes); 1237 FieldDescriptor new_field(name, index, attributes);
1225 Object* new_descriptors = 1238 Object* new_descriptors;
1226 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); 1239 { TryAllocation t =
1227 if (new_descriptors->IsFailure()) return new_descriptors; 1240 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS);
1241 if (!t->ToObject(&new_descriptors)) return t;
1242 }
1228 1243
1229 // Only allow map transition if the object's map is NOT equal to the 1244 // Only allow map transition if the object's map is NOT equal to the
1230 // global object_function's map and there is not a transition for name. 1245 // global object_function's map and there is not a transition for name.
1231 bool allow_map_transition = 1246 bool allow_map_transition =
1232 !old_descriptors->Contains(name) && 1247 !old_descriptors->Contains(name) &&
1233 (Top::context()->global_context()->object_function()->map() != map()); 1248 (Top::context()->global_context()->object_function()->map() != map());
1234 1249
1235 ASSERT(index < map()->inobject_properties() || 1250 ASSERT(index < map()->inobject_properties() ||
1236 (index - map()->inobject_properties()) < properties()->length() || 1251 (index - map()->inobject_properties()) < properties()->length() ||
1237 map()->unused_property_fields() == 0); 1252 map()->unused_property_fields() == 0);
1253 Object* r;
1254 { TryAllocation t = map()->CopyDropDescriptors();
1255 if (!t->ToObject(&r)) return t;
1256 }
1238 // Allocate a new map for the object. 1257 // Allocate a new map for the object.
1239 Object* r = map()->CopyDropDescriptors();
1240 if (r->IsFailure()) return r;
1241 Map* new_map = Map::cast(r); 1258 Map* new_map = Map::cast(r);
1242 if (allow_map_transition) { 1259 if (allow_map_transition) {
1243 // Allocate new instance descriptors for the old map with map transition. 1260 // Allocate new instance descriptors for the old map with map transition.
1261 Object* r;
1262 { TryAllocation t = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
1263 if (!t->ToObject(&r)) return t;
1264 }
1244 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); 1265 MapTransitionDescriptor d(name, Map::cast(new_map), attributes);
1245 Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS);
1246 if (r->IsFailure()) return r;
1247 old_descriptors = DescriptorArray::cast(r); 1266 old_descriptors = DescriptorArray::cast(r);
1248 } 1267 }
1249 1268
1250 if (map()->unused_property_fields() == 0) { 1269 if (map()->unused_property_fields() == 0) {
1270 Object* obj;
1271 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1272 if (!t->ToObject(&obj)) return t;
1273 }
1251 if (properties()->length() > MaxFastProperties()) { 1274 if (properties()->length() > MaxFastProperties()) {
1252 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1253 if (obj->IsFailure()) return obj;
1254 return AddSlowProperty(name, value, attributes); 1275 return AddSlowProperty(name, value, attributes);
1255 } 1276 }
1256 // Make room for the new value 1277 // Make room for the new value
1257 Object* values = 1278 Object* values;
1258 properties()->CopySize(properties()->length() + kFieldsAdded); 1279 { TryAllocation t =
1259 if (values->IsFailure()) return values; 1280 properties()->CopySize(properties()->length() + kFieldsAdded);
1281 if (!t->ToObject(&values)) return t;
1282 }
1260 set_properties(FixedArray::cast(values)); 1283 set_properties(FixedArray::cast(values));
1261 new_map->set_unused_property_fields(kFieldsAdded - 1); 1284 new_map->set_unused_property_fields(kFieldsAdded - 1);
1262 } else { 1285 } else {
1263 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); 1286 new_map->set_unused_property_fields(map()->unused_property_fields() - 1);
1264 } 1287 }
1265 // We have now allocated all the necessary objects. 1288 // We have now allocated all the necessary objects.
1266 // All the changes can be applied at once, so they are atomic. 1289 // All the changes can be applied at once, so they are atomic.
1267 map()->set_instance_descriptors(old_descriptors); 1290 map()->set_instance_descriptors(old_descriptors);
1268 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 1291 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
1269 set_map(new_map); 1292 set_map(new_map);
1270 return FastPropertyAtPut(index, value); 1293 return FastPropertyAtPut(index, value);
1271 } 1294 }
1272 1295
1273 1296
1274 Object* JSObject::AddConstantFunctionProperty(String* name, 1297 Object* JSObject::AddConstantFunctionProperty(String* name,
1275 JSFunction* function, 1298 JSFunction* function,
1276 PropertyAttributes attributes) { 1299 PropertyAttributes attributes) {
1277 ASSERT(!Heap::InNewSpace(function)); 1300 ASSERT(!Heap::InNewSpace(function));
1278 1301
1279 // Allocate new instance descriptors with (name, function) added 1302 // Allocate new instance descriptors with (name, function) added
1280 ConstantFunctionDescriptor d(name, function, attributes); 1303 ConstantFunctionDescriptor d(name, function, attributes);
1281 Object* new_descriptors = 1304 Object* new_descriptors;
1282 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); 1305 { TryAllocation t =
1283 if (new_descriptors->IsFailure()) return new_descriptors; 1306 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS);
1307 if (!t->ToObject(&new_descriptors)) return t;
1308 }
1284 1309
1310 Object* new_map;
1311 { TryAllocation t = map()->CopyDropDescriptors();
1312 if (!t->ToObject(&new_map)) return t;
1313 }
1285 // Allocate a new map for the object. 1314 // Allocate a new map for the object.
1286 Object* new_map = map()->CopyDropDescriptors();
1287 if (new_map->IsFailure()) return new_map;
1288 1315
1289 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); 1316 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors);
1290 Map::cast(new_map)->set_instance_descriptors(descriptors); 1317 Map::cast(new_map)->set_instance_descriptors(descriptors);
1291 Map* old_map = map(); 1318 Map* old_map = map();
1292 set_map(Map::cast(new_map)); 1319 set_map(Map::cast(new_map));
1293 1320
1294 // If the old map is the global object map (from new Object()), 1321 // If the old map is the global object map (from new Object()),
1295 // then transitions are not added to it, so we are done. 1322 // then transitions are not added to it, so we are done.
1296 if (old_map == Top::context()->global_context()->object_function()->map()) { 1323 if (old_map == Top::context()->global_context()->object_function()->map()) {
1297 return function; 1324 return function;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 if (entry != StringDictionary::kNotFound) { 1361 if (entry != StringDictionary::kNotFound) {
1335 store_value = dict->ValueAt(entry); 1362 store_value = dict->ValueAt(entry);
1336 JSGlobalPropertyCell::cast(store_value)->set_value(value); 1363 JSGlobalPropertyCell::cast(store_value)->set_value(value);
1337 // Assign an enumeration index to the property and update 1364 // Assign an enumeration index to the property and update
1338 // SetNextEnumerationIndex. 1365 // SetNextEnumerationIndex.
1339 int index = dict->NextEnumerationIndex(); 1366 int index = dict->NextEnumerationIndex();
1340 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); 1367 PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
1341 dict->SetNextEnumerationIndex(index + 1); 1368 dict->SetNextEnumerationIndex(index + 1);
1342 dict->SetEntry(entry, name, store_value, details); 1369 dict->SetEntry(entry, name, store_value, details);
1343 return value; 1370 return value;
1371 { TryAllocation t = Heap::AllocateJSGlobalPropertyCell(value);
1372 if (!t->ToObject(&store_value)) return t;
1344 } 1373 }
1345 store_value = Heap::AllocateJSGlobalPropertyCell(value); 1374 }
1346 if (store_value->IsFailure()) return store_value;
1347 JSGlobalPropertyCell::cast(store_value)->set_value(value); 1375 JSGlobalPropertyCell::cast(store_value)->set_value(value);
1348 } 1376 }
1377 Object* result;
1378 { TryAllocation t = dict->Add(name, store_value, details);
1379 if (!t->ToObject(&result)) return t;
1380 }
1349 PropertyDetails details = PropertyDetails(attributes, NORMAL); 1381 PropertyDetails details = PropertyDetails(attributes, NORMAL);
1350 Object* result = dict->Add(name, store_value, details);
1351 if (result->IsFailure()) return result;
1352 if (dict != result) set_properties(StringDictionary::cast(result)); 1382 if (dict != result) set_properties(StringDictionary::cast(result));
1353 return value; 1383 return value;
1354 } 1384 }
1355 1385
1356 1386
1357 Object* JSObject::AddProperty(String* name, 1387 Object* JSObject::AddProperty(String* name,
1358 Object* value, 1388 Object* value,
1359 PropertyAttributes attributes) { 1389 PropertyAttributes attributes) {
1360 ASSERT(!IsJSGlobalProxy()); 1390 ASSERT(!IsJSGlobalProxy());
1361 if (!map()->is_extensible()) { 1391 if (!map()->is_extensible()) {
1362 Handle<Object> args[1] = {Handle<String>(name)}; 1392 Handle<Object> args[1] = {Handle<String>(name)};
1363 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 1393 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
1364 HandleVector(args, 1))); 1394 HandleVector(args, 1)));
1365 } 1395 }
1366 if (HasFastProperties()) { 1396 if (HasFastProperties()) {
1367 // Ensure the descriptor array does not get too big. 1397 // Ensure the descriptor array does not get too big.
1368 if (map()->instance_descriptors()->number_of_descriptors() < 1398 if (map()->instance_descriptors()->number_of_descriptors() <
1369 DescriptorArray::kMaxNumberOfDescriptors) { 1399 DescriptorArray::kMaxNumberOfDescriptors) {
1370 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { 1400 if (value->IsJSFunction() && !Heap::InNewSpace(value)) {
1371 return AddConstantFunctionProperty(name, 1401 return AddConstantFunctionProperty(name,
1372 JSFunction::cast(value), 1402 JSFunction::cast(value),
1373 attributes); 1403 attributes);
1374 } else { 1404 } else {
1375 return AddFastProperty(name, value, attributes); 1405 return AddFastProperty(name, value, attributes);
1376 } 1406 }
1377 } else { 1407 } else {
1378 // Normalize the object to prevent very large instance descriptors. 1408 // Normalize the object to prevent very large instance descriptors.
1409 Object* obj;
1410 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1411 if (!t->ToObject(&obj)) return t;
1412 }
1379 // This eliminates unwanted N^2 allocation and lookup behavior. 1413 // This eliminates unwanted N^2 allocation and lookup behavior.
1380 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1381 if (obj->IsFailure()) return obj;
1382 } 1414 }
1383 } 1415 }
1384 return AddSlowProperty(name, value, attributes); 1416 return AddSlowProperty(name, value, attributes);
1385 } 1417 }
1386 1418
1387 1419
1388 Object* JSObject::SetPropertyPostInterceptor(String* name, 1420 Object* JSObject::SetPropertyPostInterceptor(String* name,
1389 Object* value, 1421 Object* value,
1390 PropertyAttributes attributes) { 1422 PropertyAttributes attributes) {
1391 // Check local property, ignore interceptor. 1423 // Check local property, ignore interceptor.
(...skipping 23 matching lines...) Expand all
1415 1447
1416 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index); 1448 PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
1417 return SetNormalizedProperty(name, value, new_details); 1449 return SetNormalizedProperty(name, value, new_details);
1418 } 1450 }
1419 1451
1420 1452
1421 Object* JSObject::ConvertDescriptorToFieldAndMapTransition( 1453 Object* JSObject::ConvertDescriptorToFieldAndMapTransition(
1422 String* name, 1454 String* name,
1423 Object* new_value, 1455 Object* new_value,
1424 PropertyAttributes attributes) { 1456 PropertyAttributes attributes) {
1457 Object* result;
1458 { TryAllocation t = ConvertDescriptorToField(name, new_value, attributes);
1459 if (!t->ToObject(&result)) return t;
1460 }
1425 Map* old_map = map(); 1461 Map* old_map = map();
1426 Object* result = ConvertDescriptorToField(name, new_value, attributes);
1427 if (result->IsFailure()) return result;
1428 // If we get to this point we have succeeded - do not return failure 1462 // If we get to this point we have succeeded - do not return failure
1429 // after this point. Later stuff is optional. 1463 // after this point. Later stuff is optional.
1430 if (!HasFastProperties()) { 1464 if (!HasFastProperties()) {
1431 return result; 1465 return result;
1432 } 1466 }
1433 // Do not add transitions to the map of "new Object()". 1467 // Do not add transitions to the map of "new Object()".
1434 if (map() == Top::context()->global_context()->object_function()->map()) { 1468 if (map() == Top::context()->global_context()->object_function()->map()) {
1435 return result; 1469 return result;
1436 } 1470 }
1437 1471
1438 MapTransitionDescriptor transition(name, 1472 MapTransitionDescriptor transition(name,
1439 map(), 1473 map(),
1440 attributes); 1474 attributes);
1441 Object* new_descriptors = 1475 Object* new_descriptors =
1442 old_map->instance_descriptors()-> 1476 old_map->instance_descriptors()->
1443 CopyInsert(&transition, KEEP_TRANSITIONS); 1477 CopyInsert(&transition, KEEP_TRANSITIONS);
1444 if (new_descriptors->IsFailure()) return result; // Yes, return _result_. 1478 if (new_descriptors->IsFailure()) return result; // Yes, return _result_.
1445 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); 1479 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors));
1446 return result; 1480 return result;
1447 } 1481 }
1448 1482
1449 1483
1450 Object* JSObject::ConvertDescriptorToField(String* name, 1484 Object* JSObject::ConvertDescriptorToField(String* name,
1451 Object* new_value, 1485 Object* new_value,
1452 PropertyAttributes attributes) { 1486 PropertyAttributes attributes) {
1453 if (map()->unused_property_fields() == 0 && 1487 if (map()->unused_property_fields() == 0 &&
1488 Object* obj;
1489 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1490 if (!t->ToObject(&obj)) return t;
1491 }
1454 properties()->length() > MaxFastProperties()) { 1492 properties()->length() > MaxFastProperties()) {
1455 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
1456 if (obj->IsFailure()) return obj;
1457 return ReplaceSlowProperty(name, new_value, attributes); 1493 return ReplaceSlowProperty(name, new_value, attributes);
1458 } 1494 }
1459 1495
1460 int index = map()->NextFreePropertyIndex(); 1496 int index = map()->NextFreePropertyIndex();
1461 FieldDescriptor new_field(name, index, attributes); 1497 FieldDescriptor new_field(name, index, attributes);
1462 // Make a new DescriptorArray replacing an entry with FieldDescriptor. 1498 // Make a new DescriptorArray replacing an entry with FieldDescriptor.
1463 Object* descriptors_unchecked = map()->instance_descriptors()-> 1499 Object* descriptors_unchecked;
1464 CopyInsert(&new_field, REMOVE_TRANSITIONS); 1500 { TryAllocation t = map()->instance_descriptors()->
1465 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; 1501 CopyInsert(&new_field, REMOVE_TRANSITIONS);
1502 if (!t->ToObject(&descriptors_unchecked)) return t;
1503 }
1466 DescriptorArray* new_descriptors = 1504 DescriptorArray* new_descriptors =
1467 DescriptorArray::cast(descriptors_unchecked); 1505 DescriptorArray::cast(descriptors_unchecked);
1468 1506
1507 Object* new_map_unchecked;
1508 { TryAllocation t = map()->CopyDropDescriptors();
1509 if (!t->ToObject(&new_map_unchecked)) return t;
1510 }
1469 // Make a new map for the object. 1511 // Make a new map for the object.
1470 Object* new_map_unchecked = map()->CopyDropDescriptors();
1471 if (new_map_unchecked->IsFailure()) return new_map_unchecked;
1472 Map* new_map = Map::cast(new_map_unchecked); 1512 Map* new_map = Map::cast(new_map_unchecked);
1473 new_map->set_instance_descriptors(new_descriptors); 1513 new_map->set_instance_descriptors(new_descriptors);
1474 1514
1475 // Make new properties array if necessary. 1515 // Make new properties array if necessary.
1476 FixedArray* new_properties = 0; // Will always be NULL or a valid pointer. 1516 FixedArray* new_properties = 0; // Will always be NULL or a valid pointer.
1477 int new_unused_property_fields = map()->unused_property_fields() - 1; 1517 int new_unused_property_fields = map()->unused_property_fields() - 1;
1478 if (map()->unused_property_fields() == 0) { 1518 if (map()->unused_property_fields() == 0) {
1479 new_unused_property_fields = kFieldsAdded - 1; 1519 new_unused_property_fields = kFieldsAdded - 1;
1480 Object* new_properties_unchecked = 1520 Object* new_properties_unchecked;
1481 properties()->CopySize(properties()->length() + kFieldsAdded); 1521 { TryAllocation t =
1482 if (new_properties_unchecked->IsFailure()) return new_properties_unchecked; 1522 properties()->CopySize(properties()->length() + kFieldsAdded);
1523 if (!t->ToObject(&new_properties_unchecked)) return t;
1524 }
1483 new_properties = FixedArray::cast(new_properties_unchecked); 1525 new_properties = FixedArray::cast(new_properties_unchecked);
1484 } 1526 }
1485 1527
1486 // Update pointers to commit changes. 1528 // Update pointers to commit changes.
1487 // Object points to the new map. 1529 // Object points to the new map.
1488 new_map->set_unused_property_fields(new_unused_property_fields); 1530 new_map->set_unused_property_fields(new_unused_property_fields);
1489 set_map(new_map); 1531 set_map(new_map);
1490 if (new_properties) { 1532 if (new_properties) {
1491 set_properties(FixedArray::cast(new_properties)); 1533 set_properties(FixedArray::cast(new_properties));
1492 } 1534 }
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
2110 Object* fresh = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); 2152 Object* fresh = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
2111 if (!fresh->IsFailure()) { 2153 if (!fresh->IsFailure()) {
2112 ASSERT(memcmp(Map::cast(fresh)->address(), 2154 ASSERT(memcmp(Map::cast(fresh)->address(),
2113 Map::cast(result)->address(), 2155 Map::cast(result)->address(),
2114 Map::kSize) == 0); 2156 Map::kSize) == 0);
2115 } 2157 }
2116 } 2158 }
2117 #endif 2159 #endif
2118 return result; 2160 return result;
2119 } 2161 }
2162 { TryAllocation t = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
2163 if (!t->ToObject(&result)) return t;
2164 }
2120 2165
2121 result = fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP);
2122 if (result->IsFailure()) return result;
2123 set(index, result); 2166 set(index, result);
2124 Counters::normalized_maps.Increment(); 2167 Counters::normalized_maps.Increment();
2125 2168
2126 return result; 2169 return result;
2127 } 2170 }
2128 2171
2129 2172
2130 void NormalizedMapCache::Clear() { 2173 void NormalizedMapCache::Clear() {
2131 int entries = length(); 2174 int entries = length();
2132 for (int i = 0; i != entries; i++) { 2175 for (int i = 0; i != entries; i++) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 slow->bit_field() == fast->bit_field() && 2212 slow->bit_field() == fast->bit_field() &&
2170 (slow->bit_field2() & ~(1<<Map::kIsShared)) == fast->bit_field2(); 2213 (slow->bit_field2() & ~(1<<Map::kIsShared)) == fast->bit_field2();
2171 } 2214 }
2172 2215
2173 2216
2174 Object* JSObject::UpdateMapCodeCache(String* name, Code* code) { 2217 Object* JSObject::UpdateMapCodeCache(String* name, Code* code) {
2175 if (map()->is_shared()) { 2218 if (map()->is_shared()) {
2176 // Fast case maps are never marked as shared. 2219 // Fast case maps are never marked as shared.
2177 ASSERT(!HasFastProperties()); 2220 ASSERT(!HasFastProperties());
2178 // Replace the map with an identical copy that can be safely modified. 2221 // Replace the map with an identical copy that can be safely modified.
2179 Object* obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, 2222 Object* obj;
2180 UNIQUE_NORMALIZED_MAP); 2223 { TryAllocation t = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES,
2181 if (obj->IsFailure()) return obj; 2224 UNIQUE_NORMALIZED_MAP);
2225 if (!t->ToObject(&obj)) return t;
2226 }
2182 Counters::normalized_maps.Increment(); 2227 Counters::normalized_maps.Increment();
2183 2228
2184 set_map(Map::cast(obj)); 2229 set_map(Map::cast(obj));
2185 } 2230 }
2186 return map()->UpdateCodeCache(name, code); 2231 return map()->UpdateCodeCache(name, code);
2187 } 2232 }
2188 2233
2189 2234
2190 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, 2235 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
2191 int expected_additional_properties) { 2236 int expected_additional_properties) {
2192 if (!HasFastProperties()) return this; 2237 if (!HasFastProperties()) return this;
2193 2238
2194 // The global object is always normalized. 2239 // The global object is always normalized.
2195 ASSERT(!IsGlobalObject()); 2240 ASSERT(!IsGlobalObject());
2196 2241
2197 // Allocate new content. 2242 // Allocate new content.
2198 int property_count = map()->NumberOfDescribedProperties(); 2243 int property_count = map()->NumberOfDescribedProperties();
2199 if (expected_additional_properties > 0) { 2244 if (expected_additional_properties > 0) {
2200 property_count += expected_additional_properties; 2245 property_count += expected_additional_properties;
2201 } else { 2246 } else {
2202 property_count += 2; // Make space for two more properties. 2247 property_count += 2; // Make space for two more properties.
2203 } 2248 }
2204 Object* obj = 2249 Object* obj;
2205 StringDictionary::Allocate(property_count); 2250 { TryAllocation t =
2206 if (obj->IsFailure()) return obj; 2251 StringDictionary::Allocate(property_count);
2252 if (!t->ToObject(&obj)) return t;
2253 }
2207 StringDictionary* dictionary = StringDictionary::cast(obj); 2254 StringDictionary* dictionary = StringDictionary::cast(obj);
2208 2255
2209 DescriptorArray* descs = map()->instance_descriptors(); 2256 DescriptorArray* descs = map()->instance_descriptors();
2210 for (int i = 0; i < descs->number_of_descriptors(); i++) { 2257 for (int i = 0; i < descs->number_of_descriptors(); i++) {
2211 PropertyDetails details = descs->GetDetails(i); 2258 PropertyDetails details = descs->GetDetails(i);
2212 switch (details.type()) { 2259 switch (details.type()) {
2213 case CONSTANT_FUNCTION: { 2260 case CONSTANT_FUNCTION: {
2214 PropertyDetails d = 2261 PropertyDetails d =
2215 PropertyDetails(details.attributes(), NORMAL, details.index()); 2262 PropertyDetails(details.attributes(), NORMAL, details.index());
2263 Object* result;
2264 { TryAllocation t = dictionary->Add(descs->GetKey(i), value, d);
2265 if (!t->ToObject(&result)) return t;
2266 }
2216 Object* value = descs->GetConstantFunction(i); 2267 Object* value = descs->GetConstantFunction(i);
2217 Object* result = dictionary->Add(descs->GetKey(i), value, d);
2218 if (result->IsFailure()) return result;
2219 dictionary = StringDictionary::cast(result); 2268 dictionary = StringDictionary::cast(result);
2220 break; 2269 break;
2221 } 2270 }
2222 case FIELD: { 2271 case FIELD: {
2223 PropertyDetails d = 2272 PropertyDetails d =
2224 PropertyDetails(details.attributes(), NORMAL, details.index()); 2273 PropertyDetails(details.attributes(), NORMAL, details.index());
2274 Object* result;
2275 { TryAllocation t = dictionary->Add(descs->GetKey(i), value, d);
2276 if (!t->ToObject(&result)) return t;
2277 }
2225 Object* value = FastPropertyAt(descs->GetFieldIndex(i)); 2278 Object* value = FastPropertyAt(descs->GetFieldIndex(i));
2226 Object* result = dictionary->Add(descs->GetKey(i), value, d);
2227 if (result->IsFailure()) return result;
2228 dictionary = StringDictionary::cast(result); 2279 dictionary = StringDictionary::cast(result);
2229 break; 2280 break;
2230 } 2281 }
2231 case CALLBACKS: { 2282 case CALLBACKS: {
2232 PropertyDetails d = 2283 PropertyDetails d =
2233 PropertyDetails(details.attributes(), CALLBACKS, details.index()); 2284 PropertyDetails(details.attributes(), CALLBACKS, details.index());
2285 Object* result;
2286 { TryAllocation t = dictionary->Add(descs->GetKey(i), value, d);
2287 if (!t->ToObject(&result)) return t;
2288 }
2234 Object* value = descs->GetCallbacksObject(i); 2289 Object* value = descs->GetCallbacksObject(i);
2235 Object* result = dictionary->Add(descs->GetKey(i), value, d);
2236 if (result->IsFailure()) return result;
2237 dictionary = StringDictionary::cast(result); 2290 dictionary = StringDictionary::cast(result);
2238 break; 2291 break;
2239 } 2292 }
2240 case MAP_TRANSITION: 2293 case MAP_TRANSITION:
2241 case CONSTANT_TRANSITION: 2294 case CONSTANT_TRANSITION:
2242 case NULL_DESCRIPTOR: 2295 case NULL_DESCRIPTOR:
2243 case INTERCEPTOR: 2296 case INTERCEPTOR:
2244 break; 2297 break;
2245 default: 2298 default:
2246 UNREACHABLE(); 2299 UNREACHABLE();
2247 } 2300 }
2248 } 2301 }
2249 2302
2250 // Copy the next enumeration index from instance descriptor. 2303 // Copy the next enumeration index from instance descriptor.
2251 int index = map()->instance_descriptors()->NextEnumerationIndex(); 2304 int index = map()->instance_descriptors()->NextEnumerationIndex();
2252 dictionary->SetNextEnumerationIndex(index); 2305 dictionary->SetNextEnumerationIndex(index);
2253 2306
2254 obj = Top::context()->global_context()-> 2307 { TryAllocation t = Top::context()->global_context()->
2255 normalized_map_cache()->Get(this, mode); 2308 normalized_map_cache()->Get(this, mode);
2256 if (obj->IsFailure()) return obj; 2309 if (!t->ToObject(&obj)) return t;
2310 }
2257 Map* new_map = Map::cast(obj); 2311 Map* new_map = Map::cast(obj);
2258 2312
2259 // We have now successfully allocated all the necessary objects. 2313 // We have now successfully allocated all the necessary objects.
2260 // Changes can now be made with the guarantee that all of them take effect. 2314 // Changes can now be made with the guarantee that all of them take effect.
2261 2315
2262 // Resize the object in the heap if necessary. 2316 // Resize the object in the heap if necessary.
2263 int new_instance_size = new_map->instance_size(); 2317 int new_instance_size = new_map->instance_size();
2264 int instance_size_delta = map()->instance_size() - new_instance_size; 2318 int instance_size_delta = map()->instance_size() - new_instance_size;
2265 ASSERT(instance_size_delta >= 0); 2319 ASSERT(instance_size_delta >= 0);
2266 Heap::CreateFillerObjectAt(this->address() + new_instance_size, 2320 Heap::CreateFillerObjectAt(this->address() + new_instance_size,
(...skipping 20 matching lines...) Expand all
2287 ASSERT(!IsGlobalObject()); 2341 ASSERT(!IsGlobalObject());
2288 return property_dictionary()-> 2342 return property_dictionary()->
2289 TransformPropertiesToFastFor(this, unused_property_fields); 2343 TransformPropertiesToFastFor(this, unused_property_fields);
2290 } 2344 }
2291 2345
2292 2346
2293 Object* JSObject::NormalizeElements() { 2347 Object* JSObject::NormalizeElements() {
2294 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 2348 ASSERT(!HasPixelElements() && !HasExternalArrayElements());
2295 if (HasDictionaryElements()) return this; 2349 if (HasDictionaryElements()) return this;
2296 ASSERT(map()->has_fast_elements()); 2350 ASSERT(map()->has_fast_elements());
2351 Object* obj;
2352 { TryAllocation t = map()->GetSlowElementsMap();
2353 if (!t->ToObject(&obj)) return t;
2354 }
2297 2355
2298 Object* obj = map()->GetSlowElementsMap();
2299 if (obj->IsFailure()) return obj;
2300 Map* new_map = Map::cast(obj); 2356 Map* new_map = Map::cast(obj);
2301 2357
2302 // Get number of entries. 2358 // Get number of entries.
2303 FixedArray* array = FixedArray::cast(elements()); 2359 FixedArray* array = FixedArray::cast(elements());
2304 2360
2305 // Compute the effective length. 2361 // Compute the effective length.
2306 int length = IsJSArray() ? 2362 int length = IsJSArray() ?
2307 Smi::cast(JSArray::cast(this)->length())->value() : 2363 Smi::cast(JSArray::cast(this)->length())->value() :
2364 { TryAllocation t = NumberDictionary::Allocate(length);
2365 if (!t->ToObject(&obj)) return t;
2366 }
2308 array->length(); 2367 array->length();
2309 obj = NumberDictionary::Allocate(length);
2310 if (obj->IsFailure()) return obj;
2311 NumberDictionary* dictionary = NumberDictionary::cast(obj); 2368 NumberDictionary* dictionary = NumberDictionary::cast(obj);
2312 // Copy entries. 2369 // Copy entries.
2313 for (int i = 0; i < length; i++) { 2370 for (int i = 0; i < length; i++) {
2314 Object* value = array->get(i); 2371 Object* value = array->get(i);
2315 if (!value->IsTheHole()) { 2372 if (!value->IsTheHole()) {
2373 Object* result;
2374 { TryAllocation t = dictionary->AddNumberEntry(i, array->get(i), details);
2375 if (!t->ToObject(&result)) return t;
2376 }
2316 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2377 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2317 Object* result = dictionary->AddNumberEntry(i, array->get(i), details);
2318 if (result->IsFailure()) return result;
2319 dictionary = NumberDictionary::cast(result); 2378 dictionary = NumberDictionary::cast(result);
2320 } 2379 }
2321 } 2380 }
2322 // Switch to using the dictionary as the backing storage for 2381 // Switch to using the dictionary as the backing storage for
2323 // elements. Set the new map first to satify the elements type 2382 // elements. Set the new map first to satify the elements type
2324 // assert in set_elements(). 2383 // assert in set_elements().
2325 set_map(new_map); 2384 set_map(new_map);
2326 set_elements(dictionary); 2385 set_elements(dictionary);
2327 2386
2328 Counters::elements_to_dictionary.Increment(); 2387 Counters::elements_to_dictionary.Increment();
2329 2388
2330 #ifdef DEBUG 2389 #ifdef DEBUG
2331 if (FLAG_trace_normalization) { 2390 if (FLAG_trace_normalization) {
2332 PrintF("Object elements have been normalized:\n"); 2391 PrintF("Object elements have been normalized:\n");
2333 Print(); 2392 Print();
2334 } 2393 }
2335 #endif 2394 #endif
2336 2395
2337 return this; 2396 return this;
2338 } 2397 }
2339 2398
2340 2399
2341 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { 2400 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) {
2342 // Check local property, ignore interceptor. 2401 // Check local property, ignore interceptor.
2343 LookupResult result; 2402 LookupResult result;
2344 LocalLookupRealNamedProperty(name, &result); 2403 LocalLookupRealNamedProperty(name, &result);
2345 if (!result.IsProperty()) return Heap::true_value(); 2404 if (!result.IsProperty()) return Heap::true_value();
2346 2405
2406 Object* obj;
2407 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2408 if (!t->ToObject(&obj)) return t;
2409 }
2347 // Normalize object if needed. 2410 // Normalize object if needed.
2348 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2349 if (obj->IsFailure()) return obj;
2350 2411
2351 return DeleteNormalizedProperty(name, mode); 2412 return DeleteNormalizedProperty(name, mode);
2352 } 2413 }
2353 2414
2354 2415
2355 Object* JSObject::DeletePropertyWithInterceptor(String* name) { 2416 Object* JSObject::DeletePropertyWithInterceptor(String* name) {
2356 HandleScope scope; 2417 HandleScope scope;
2357 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); 2418 Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
2358 Handle<String> name_handle(name); 2419 Handle<String> name_handle(name);
2359 Handle<JSObject> this_handle(this); 2420 Handle<JSObject> this_handle(this);
(...skipping 19 matching lines...) Expand all
2379 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); 2440 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION);
2380 RETURN_IF_SCHEDULED_EXCEPTION(); 2441 RETURN_IF_SCHEDULED_EXCEPTION();
2381 return raw_result; 2442 return raw_result;
2382 } 2443 }
2383 2444
2384 2445
2385 Object* JSObject::DeleteElementPostInterceptor(uint32_t index, 2446 Object* JSObject::DeleteElementPostInterceptor(uint32_t index,
2386 DeleteMode mode) { 2447 DeleteMode mode) {
2387 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 2448 ASSERT(!HasPixelElements() && !HasExternalArrayElements());
2388 switch (GetElementsKind()) { 2449 switch (GetElementsKind()) {
2450 Object* obj;
2451 { TryAllocation t = EnsureWritableFastElements();
2452 if (!t->ToObject(&obj)) return t;
2453 }
2389 case FAST_ELEMENTS: { 2454 case FAST_ELEMENTS: {
2390 Object* obj = EnsureWritableFastElements();
2391 if (obj->IsFailure()) return obj;
2392 uint32_t length = IsJSArray() ? 2455 uint32_t length = IsJSArray() ?
2393 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2456 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2394 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2457 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2395 if (index < length) { 2458 if (index < length) {
2396 FixedArray::cast(elements())->set_the_hole(index); 2459 FixedArray::cast(elements())->set_the_hole(index);
2397 } 2460 }
2398 break; 2461 break;
2399 } 2462 }
2400 case DICTIONARY_ELEMENTS: { 2463 case DICTIONARY_ELEMENTS: {
2401 NumberDictionary* dictionary = element_dictionary(); 2464 NumberDictionary* dictionary = element_dictionary();
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 2524
2462 if (HasIndexedInterceptor()) { 2525 if (HasIndexedInterceptor()) {
2463 // Skip interceptor if forcing deletion. 2526 // Skip interceptor if forcing deletion.
2464 if (mode == FORCE_DELETION) { 2527 if (mode == FORCE_DELETION) {
2465 return DeleteElementPostInterceptor(index, mode); 2528 return DeleteElementPostInterceptor(index, mode);
2466 } 2529 }
2467 return DeleteElementWithInterceptor(index); 2530 return DeleteElementWithInterceptor(index);
2468 } 2531 }
2469 2532
2470 switch (GetElementsKind()) { 2533 switch (GetElementsKind()) {
2534 Object* obj;
2535 { TryAllocation t = EnsureWritableFastElements();
2536 if (!t->ToObject(&obj)) return t;
2537 }
2471 case FAST_ELEMENTS: { 2538 case FAST_ELEMENTS: {
2472 Object* obj = EnsureWritableFastElements();
2473 if (obj->IsFailure()) return obj;
2474 uint32_t length = IsJSArray() ? 2539 uint32_t length = IsJSArray() ?
2475 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : 2540 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) :
2476 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 2541 static_cast<uint32_t>(FixedArray::cast(elements())->length());
2477 if (index < length) { 2542 if (index < length) {
2478 FixedArray::cast(elements())->set_the_hole(index); 2543 FixedArray::cast(elements())->set_the_hole(index);
2479 } 2544 }
2480 break; 2545 break;
2481 } 2546 }
2482 case PIXEL_ELEMENTS: 2547 case PIXEL_ELEMENTS:
2483 case EXTERNAL_BYTE_ELEMENTS: 2548 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2536 return Heap::false_value(); 2601 return Heap::false_value();
2537 } 2602 }
2538 // Check for interceptor. 2603 // Check for interceptor.
2539 if (result.type() == INTERCEPTOR) { 2604 if (result.type() == INTERCEPTOR) {
2540 // Skip interceptor if forcing a deletion. 2605 // Skip interceptor if forcing a deletion.
2541 if (mode == FORCE_DELETION) { 2606 if (mode == FORCE_DELETION) {
2542 return DeletePropertyPostInterceptor(name, mode); 2607 return DeletePropertyPostInterceptor(name, mode);
2543 } 2608 }
2544 return DeletePropertyWithInterceptor(name); 2609 return DeletePropertyWithInterceptor(name);
2545 } 2610 }
2611 Object* obj;
2612 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2613 if (!t->ToObject(&obj)) return t;
2614 }
2546 // Normalize object if needed. 2615 // Normalize object if needed.
2547 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2548 if (obj->IsFailure()) return obj;
2549 // Make sure the properties are normalized before removing the entry. 2616 // Make sure the properties are normalized before removing the entry.
2550 return DeleteNormalizedProperty(name, mode); 2617 return DeleteNormalizedProperty(name, mode);
2551 } 2618 }
2552 } 2619 }
2553 2620
2554 2621
2555 // Check whether this object references another object. 2622 // Check whether this object references another object.
2556 bool JSObject::ReferencesObject(Object* obj) { 2623 bool JSObject::ReferencesObject(Object* obj) {
2557 AssertNoAllocation no_alloc; 2624 AssertNoAllocation no_alloc;
2558 2625
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
2646 } 2713 }
2647 } 2714 }
2648 2715
2649 // No references to object. 2716 // No references to object.
2650 return false; 2717 return false;
2651 } 2718 }
2652 2719
2653 2720
2654 Object* JSObject::PreventExtensions() { 2721 Object* JSObject::PreventExtensions() {
2655 // If there are fast elements we normalize. 2722 // If there are fast elements we normalize.
2723 Object* ok;
2724 { TryAllocation t = NormalizeElements();
2725 if (!t->ToObject(&ok)) return t;
2726 }
2656 if (HasFastElements()) { 2727 if (HasFastElements()) {
2657 Object* ok = NormalizeElements();
2658 if (ok->IsFailure()) return ok;
2659 } 2728 }
2660 // Make sure that we never go back to fast case. 2729 // Make sure that we never go back to fast case.
2661 element_dictionary()->set_requires_slow_elements(); 2730 element_dictionary()->set_requires_slow_elements();
2662 2731
2663 // Do a map transition, other objects with this map may still 2732 // Do a map transition, other objects with this map may still
2733 Object* new_map;
2734 { TryAllocation t = map()->CopyDropTransitions();
2735 if (!t->ToObject(&new_map)) return t;
2736 }
2664 // be extensible. 2737 // be extensible.
2665 Object* new_map = map()->CopyDropTransitions();
2666 if (new_map->IsFailure()) return new_map;
2667 Map::cast(new_map)->set_is_extensible(false); 2738 Map::cast(new_map)->set_is_extensible(false);
2668 set_map(Map::cast(new_map)); 2739 set_map(Map::cast(new_map));
2669 ASSERT(!map()->is_extensible()); 2740 ASSERT(!map()->is_extensible());
2670 return new_map; 2741 return new_map;
2671 } 2742 }
2672 2743
2673 2744
2674 // Tests for the fast common case for property enumeration: 2745 // Tests for the fast common case for property enumeration:
2675 // - This object and all prototypes has an enum cache (which means that it has 2746 // - This object and all prototypes has an enum cache (which means that it has
2676 // no interceptors and needs no access checks). 2747 // no interceptors and needs no access checks).
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
2860 Object* obj = result.GetCallbackObject(); 2931 Object* obj = result.GetCallbackObject();
2861 // Need to preserve old getters/setters. 2932 // Need to preserve old getters/setters.
2862 if (obj->IsFixedArray()) { 2933 if (obj->IsFixedArray()) {
2863 // Use set to update attributes. 2934 // Use set to update attributes.
2864 return SetPropertyCallback(name, obj, attributes); 2935 return SetPropertyCallback(name, obj, attributes);
2865 } 2936 }
2866 } 2937 }
2867 } 2938 }
2868 } 2939 }
2869 2940
2941 Object* structure;
2942 { TryAllocation t = Heap::AllocateFixedArray(2, TENURED);
2943 if (!t->ToObject(&structure)) return t;
2944 }
2870 // Allocate the fixed array to hold getter and setter. 2945 // Allocate the fixed array to hold getter and setter.
2871 Object* structure = Heap::AllocateFixedArray(2, TENURED);
2872 if (structure->IsFailure()) return structure;
2873 2946
2874 if (is_element) { 2947 if (is_element) {
2875 return SetElementCallback(index, structure, attributes); 2948 return SetElementCallback(index, structure, attributes);
2876 } else { 2949 } else {
2877 return SetPropertyCallback(name, structure, attributes); 2950 return SetPropertyCallback(name, structure, attributes);
2878 } 2951 }
2879 } 2952 }
2880 2953
2881 2954
2882 bool JSObject::CanSetCallback(String* name) { 2955 bool JSObject::CanSetCallback(String* name) {
(...skipping 18 matching lines...) Expand all
2901 2974
2902 return true; 2975 return true;
2903 } 2976 }
2904 2977
2905 2978
2906 Object* JSObject::SetElementCallback(uint32_t index, 2979 Object* JSObject::SetElementCallback(uint32_t index,
2907 Object* structure, 2980 Object* structure,
2908 PropertyAttributes attributes) { 2981 PropertyAttributes attributes) {
2909 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 2982 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
2910 2983
2984 Object* ok;
2985 { TryAllocation t = NormalizeElements();
2986 if (!t->ToObject(&ok)) return t;
2987 }
2911 // Normalize elements to make this operation simple. 2988 // Normalize elements to make this operation simple.
2912 Object* ok = NormalizeElements();
2913 if (ok->IsFailure()) return ok;
2914 2989
2915 // Update the dictionary with the new CALLBACKS property. 2990 // Update the dictionary with the new CALLBACKS property.
2916 Object* dict = 2991 Object* dict;
2917 element_dictionary()->Set(index, structure, details); 2992 { TryAllocation t =
2918 if (dict->IsFailure()) return dict; 2993 element_dictionary()->Set(index, structure, details);
2994 if (!t->ToObject(&dict)) return t;
2995 }
2919 2996
2920 NumberDictionary* elements = NumberDictionary::cast(dict); 2997 NumberDictionary* elements = NumberDictionary::cast(dict);
2921 elements->set_requires_slow_elements(); 2998 elements->set_requires_slow_elements();
2922 // Set the potential new dictionary on the object. 2999 // Set the potential new dictionary on the object.
2923 set_elements(elements); 3000 set_elements(elements);
2924 3001
2925 return structure; 3002 return structure;
2926 } 3003 }
2927 3004
2928 3005
2929 Object* JSObject::SetPropertyCallback(String* name, 3006 Object* JSObject::SetPropertyCallback(String* name,
2930 Object* structure, 3007 Object* structure,
2931 PropertyAttributes attributes) { 3008 PropertyAttributes attributes) {
2932 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 3009 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
2933 3010
2934 bool convert_back_to_fast = HasFastProperties() && 3011 bool convert_back_to_fast = HasFastProperties() &&
2935 (map()->instance_descriptors()->number_of_descriptors() 3012 (map()->instance_descriptors()->number_of_descriptors()
2936 < DescriptorArray::kMaxNumberOfDescriptors); 3013 < DescriptorArray::kMaxNumberOfDescriptors);
2937 3014
3015 Object* ok;
3016 { TryAllocation t = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
3017 if (!t->ToObject(&ok)) return t;
3018 }
2938 // Normalize object to make this operation simple. 3019 // Normalize object to make this operation simple.
2939 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
2940 if (ok->IsFailure()) return ok;
2941 3020
2942 // For the global object allocate a new map to invalidate the global inline 3021 // For the global object allocate a new map to invalidate the global inline
2943 // caches which have a global property cell reference directly in the code. 3022 // caches which have a global property cell reference directly in the code.
3023 Object* new_map;
3024 { TryAllocation t = map()->CopyDropDescriptors();
3025 if (!t->ToObject(&new_map)) return t;
3026 }
2944 if (IsGlobalObject()) { 3027 if (IsGlobalObject()) {
2945 Object* new_map = map()->CopyDropDescriptors();
2946 if (new_map->IsFailure()) return new_map;
2947 set_map(Map::cast(new_map)); 3028 set_map(Map::cast(new_map));
2948 } 3029 }
2949 3030
3031 Object* result;
3032 { TryAllocation t = SetNormalizedProperty(name, structure, details);
3033 if (!t->ToObject(&result)) return t;
3034 }
2950 // Update the dictionary with the new CALLBACKS property. 3035 // Update the dictionary with the new CALLBACKS property.
2951 Object* result = SetNormalizedProperty(name, structure, details);
2952 if (result->IsFailure()) return result;
2953 3036
3037 { TryAllocation t = TransformToFastProperties(0);
3038 if (!t->ToObject(&ok)) return t;
3039 }
2954 if (convert_back_to_fast) { 3040 if (convert_back_to_fast) {
2955 ok = TransformToFastProperties(0);
2956 if (ok->IsFailure()) return ok;
2957 } 3041 }
2958 return result; 3042 return result;
2959 } 3043 }
2960 3044
2961 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, 3045 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun,
2962 PropertyAttributes attributes) { 3046 PropertyAttributes attributes) {
2963 // Check access rights if needed. 3047 // Check access rights if needed.
2964 if (IsAccessCheckNeeded() && 3048 if (IsAccessCheckNeeded() &&
2965 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { 3049 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {
2966 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); 3050 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3029 case EXTERNAL_FLOAT_ELEMENTS: 3113 case EXTERNAL_FLOAT_ELEMENTS:
3030 // Ignore getters and setters on pixel and external array 3114 // Ignore getters and setters on pixel and external array
3031 // elements. 3115 // elements.
3032 return Heap::undefined_value(); 3116 return Heap::undefined_value();
3033 case DICTIONARY_ELEMENTS: 3117 case DICTIONARY_ELEMENTS:
3034 break; 3118 break;
3035 default: 3119 default:
3036 UNREACHABLE(); 3120 UNREACHABLE();
3037 break; 3121 break;
3038 } 3122 }
3123 Object* ok;
3124 { TryAllocation t =
3125 SetElementCallback(index, info, info->property_attributes());
3126 if (!t->ToObject(&ok)) return t;
3127 }
3039 3128
3040 Object* ok = SetElementCallback(index, info, info->property_attributes());
3041 if (ok->IsFailure()) return ok;
3042 } else { 3129 } else {
3043 // Lookup the name. 3130 // Lookup the name.
3044 LookupResult result; 3131 LookupResult result;
3045 LocalLookup(name, &result); 3132 LocalLookup(name, &result);
3046 // ES5 forbids turning a property into an accessor if it's not 3133 // ES5 forbids turning a property into an accessor if it's not
3047 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). 3134 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
3048 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { 3135 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) {
3049 return Heap::undefined_value(); 3136 return Heap::undefined_value();
3137 Object* ok;
3138 { TryAllocation t =
3139 SetPropertyCallback(name, info, info->property_attributes());
3140 if (!t->ToObject(&ok)) return t;
3050 } 3141 }
3051 Object* ok = SetPropertyCallback(name, info, info->property_attributes()); 3142 }
3052 if (ok->IsFailure()) return ok;
3053 } 3143 }
3054 3144
3055 return this; 3145 return this;
3056 } 3146 }
3057 3147
3058 3148
3059 Object* JSObject::LookupAccessor(String* name, bool is_getter) { 3149 Object* JSObject::LookupAccessor(String* name, bool is_getter) {
3060 // Make sure that the top context does not change when doing callbacks or 3150 // Make sure that the top context does not change when doing callbacks or
3061 // interceptor calls. 3151 // interceptor calls.
3062 AssertNoContextChange ncc; 3152 AssertNoContextChange ncc;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3125 } 3215 }
3126 } 3216 }
3127 } 3217 }
3128 return Heap::undefined_value(); 3218 return Heap::undefined_value();
3129 } else { 3219 } else {
3130 return property_dictionary()->SlowReverseLookup(value); 3220 return property_dictionary()->SlowReverseLookup(value);
3131 } 3221 }
3132 } 3222 }
3133 3223
3134 3224
3225 Object* result;
3226 { TryAllocation t = Heap::AllocateMap(instance_type(), instance_size());
3227 if (!t->ToObject(&result)) return t;
3228 }
3135 Object* Map::CopyDropDescriptors() { 3229 Object* Map::CopyDropDescriptors() {
3136 Object* result = Heap::AllocateMap(instance_type(), instance_size());
3137 if (result->IsFailure()) return result;
3138 Map::cast(result)->set_prototype(prototype()); 3230 Map::cast(result)->set_prototype(prototype());
3139 Map::cast(result)->set_constructor(constructor()); 3231 Map::cast(result)->set_constructor(constructor());
3140 // Don't copy descriptors, so map transitions always remain a forest. 3232 // Don't copy descriptors, so map transitions always remain a forest.
3141 // If we retained the same descriptors we would have two maps 3233 // If we retained the same descriptors we would have two maps
3142 // pointing to the same transition which is bad because the garbage 3234 // pointing to the same transition which is bad because the garbage
3143 // collector relies on being able to reverse pointers from transitions 3235 // collector relies on being able to reverse pointers from transitions
3144 // to maps. If properties need to be retained use CopyDropTransitions. 3236 // to maps. If properties need to be retained use CopyDropTransitions.
3145 Map::cast(result)->set_instance_descriptors(Heap::empty_descriptor_array()); 3237 Map::cast(result)->set_instance_descriptors(Heap::empty_descriptor_array());
3146 // Please note instance_type and instance_size are set when allocated. 3238 // Please note instance_type and instance_size are set when allocated.
3147 Map::cast(result)->set_inobject_properties(inobject_properties()); 3239 Map::cast(result)->set_inobject_properties(inobject_properties());
3148 Map::cast(result)->set_unused_property_fields(unused_property_fields()); 3240 Map::cast(result)->set_unused_property_fields(unused_property_fields());
3149 3241
3150 // If the map has pre-allocated properties always start out with a descriptor 3242 // If the map has pre-allocated properties always start out with a descriptor
3151 // array describing these properties. 3243 // array describing these properties.
3152 if (pre_allocated_property_fields() > 0) { 3244 if (pre_allocated_property_fields() > 0) {
3153 ASSERT(constructor()->IsJSFunction()); 3245 ASSERT(constructor()->IsJSFunction());
3154 JSFunction* ctor = JSFunction::cast(constructor()); 3246 JSFunction* ctor = JSFunction::cast(constructor());
3155 Object* descriptors = 3247 Object* descriptors;
3156 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); 3248 { TryAllocation t =
3157 if (descriptors->IsFailure()) return descriptors; 3249 ctor->initial_map()->instance_descriptors()->RemoveTransitions();
3250 if (!t->ToObject(&descriptors)) return t;
3251 }
3158 Map::cast(result)->set_instance_descriptors( 3252 Map::cast(result)->set_instance_descriptors(
3159 DescriptorArray::cast(descriptors)); 3253 DescriptorArray::cast(descriptors));
3160 Map::cast(result)->set_pre_allocated_property_fields( 3254 Map::cast(result)->set_pre_allocated_property_fields(
3161 pre_allocated_property_fields()); 3255 pre_allocated_property_fields());
3162 } 3256 }
3163 Map::cast(result)->set_bit_field(bit_field()); 3257 Map::cast(result)->set_bit_field(bit_field());
3164 Map::cast(result)->set_bit_field2(bit_field2()); 3258 Map::cast(result)->set_bit_field2(bit_field2());
3165 Map::cast(result)->set_is_shared(false); 3259 Map::cast(result)->set_is_shared(false);
3166 Map::cast(result)->ClearCodeCache(); 3260 Map::cast(result)->ClearCodeCache();
3167 return result; 3261 return result;
3168 } 3262 }
3169 3263
3170 3264
3171 Object* Map::CopyNormalized(PropertyNormalizationMode mode, 3265 Object* Map::CopyNormalized(PropertyNormalizationMode mode,
3172 NormalizedMapSharingMode sharing) { 3266 NormalizedMapSharingMode sharing) {
3173 int new_instance_size = instance_size(); 3267 int new_instance_size = instance_size();
3174 if (mode == CLEAR_INOBJECT_PROPERTIES) { 3268 if (mode == CLEAR_INOBJECT_PROPERTIES) {
3175 new_instance_size -= inobject_properties() * kPointerSize; 3269 new_instance_size -= inobject_properties() * kPointerSize;
3176 } 3270 }
3271 Object* result;
3272 { TryAllocation t = Heap::AllocateMap(instance_type(), new_instance_size);
3273 if (!t->ToObject(&result)) return t;
3274 }
3177 3275
3178 Object* result = Heap::AllocateMap(instance_type(), new_instance_size);
3179 if (result->IsFailure()) return result;
3180 3276
3181 if (mode != CLEAR_INOBJECT_PROPERTIES) { 3277 if (mode != CLEAR_INOBJECT_PROPERTIES) {
3182 Map::cast(result)->set_inobject_properties(inobject_properties()); 3278 Map::cast(result)->set_inobject_properties(inobject_properties());
3183 } 3279 }
3184 3280
3185 Map::cast(result)->set_prototype(prototype()); 3281 Map::cast(result)->set_prototype(prototype());
3186 Map::cast(result)->set_constructor(constructor()); 3282 Map::cast(result)->set_constructor(constructor());
3187 3283
3188 Map::cast(result)->set_bit_field(bit_field()); 3284 Map::cast(result)->set_bit_field(bit_field());
3189 Map::cast(result)->set_bit_field2(bit_field2()); 3285 Map::cast(result)->set_bit_field2(bit_field2());
3190 3286
3191 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP); 3287 Map::cast(result)->set_is_shared(sharing == SHARED_NORMALIZED_MAP);
3192 3288
3193 #ifdef DEBUG 3289 #ifdef DEBUG
3194 if (Map::cast(result)->is_shared()) { 3290 if (Map::cast(result)->is_shared()) {
3195 Map::cast(result)->SharedMapVerify(); 3291 Map::cast(result)->SharedMapVerify();
3196 } 3292 }
3197 #endif 3293 #endif
3198 3294
3199 return result; 3295 return result;
3200 } 3296 }
3201 3297
3202 3298
3299 Object* new_map;
3300 { TryAllocation t = CopyDropDescriptors();
3301 if (!t->ToObject(&new_map)) return t;
3302 }
3203 Object* Map::CopyDropTransitions() { 3303 Object* Map::CopyDropTransitions() {
3204 Object* new_map = CopyDropDescriptors(); 3304 Object* descriptors;
3205 if (new_map->IsFailure()) return new_map; 3305 { TryAllocation t = instance_descriptors()->RemoveTransitions();
3206 Object* descriptors = instance_descriptors()->RemoveTransitions(); 3306 if (!t->ToObject(&descriptors)) return t;
3207 if (descriptors->IsFailure()) return descriptors; 3307 }
3208 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); 3308 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
3209 return new_map; 3309 return new_map;
3210 } 3310 }
3211 3311
3212 3312
3213 Object* Map::UpdateCodeCache(String* name, Code* code) { 3313 Object* Map::UpdateCodeCache(String* name, Code* code) {
3214 // Allocate the code cache if not present. 3314 // Allocate the code cache if not present.
3315 Object* result;
3316 { TryAllocation t = Heap::AllocateCodeCache();
3317 if (!t->ToObject(&result)) return t;
3318 }
3215 if (code_cache()->IsFixedArray()) { 3319 if (code_cache()->IsFixedArray()) {
3216 Object* result = Heap::AllocateCodeCache();
3217 if (result->IsFailure()) return result;
3218 set_code_cache(result); 3320 set_code_cache(result);
3219 } 3321 }
3220 3322
3221 // Update the code cache. 3323 // Update the code cache.
3222 return CodeCache::cast(code_cache())->Update(name, code); 3324 return CodeCache::cast(code_cache())->Update(name, code);
3223 } 3325 }
3224 3326
3225 3327
3226 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { 3328 Object* Map::FindInCodeCache(String* name, Code::Flags flags) {
3227 // Do a lookup if a code cache exists. 3329 // Do a lookup if a code cache exists.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
3293 3395
3294 Object* CodeCache::Update(String* name, Code* code) { 3396 Object* CodeCache::Update(String* name, Code* code) {
3295 ASSERT(code->ic_state() == MONOMORPHIC); 3397 ASSERT(code->ic_state() == MONOMORPHIC);
3296 3398
3297 // The number of monomorphic stubs for normal load/store/call IC's can grow to 3399 // The number of monomorphic stubs for normal load/store/call IC's can grow to
3298 // a large number and therefore they need to go into a hash table. They are 3400 // a large number and therefore they need to go into a hash table. They are
3299 // used to load global properties from cells. 3401 // used to load global properties from cells.
3300 if (code->type() == NORMAL) { 3402 if (code->type() == NORMAL) {
3301 // Make sure that a hash table is allocated for the normal load code cache. 3403 // Make sure that a hash table is allocated for the normal load code cache.
3302 if (normal_type_cache()->IsUndefined()) { 3404 if (normal_type_cache()->IsUndefined()) {
3303 Object* result = 3405 Object* result;
3304 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize); 3406 { TryAllocation t =
3305 if (result->IsFailure()) return result; 3407 CodeCacheHashTable::Allocate(CodeCacheHashTable::kInitialSize);
3408 if (!t->ToObject(&result)) return t;
3409 }
3306 set_normal_type_cache(result); 3410 set_normal_type_cache(result);
3307 } 3411 }
3308 return UpdateNormalTypeCache(name, code); 3412 return UpdateNormalTypeCache(name, code);
3309 } else { 3413 } else {
3310 ASSERT(default_cache()->IsFixedArray()); 3414 ASSERT(default_cache()->IsFixedArray());
3311 return UpdateDefaultCache(name, code); 3415 return UpdateDefaultCache(name, code);
3312 } 3416 }
3313 } 3417 }
3314 3418
3315 3419
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 if (deleted_index >= 0) { 3455 if (deleted_index >= 0) {
3352 cache->set(deleted_index + kCodeCacheEntryNameOffset, name); 3456 cache->set(deleted_index + kCodeCacheEntryNameOffset, name);
3353 cache->set(deleted_index + kCodeCacheEntryCodeOffset, code); 3457 cache->set(deleted_index + kCodeCacheEntryCodeOffset, code);
3354 return this; 3458 return this;
3355 } 3459 }
3356 3460
3357 // Extend the code cache with some new entries (at least one). Must be a 3461 // Extend the code cache with some new entries (at least one). Must be a
3358 // multiple of the entry size. 3462 // multiple of the entry size.
3359 int new_length = length + ((length >> 1)) + kCodeCacheEntrySize; 3463 int new_length = length + ((length >> 1)) + kCodeCacheEntrySize;
3360 new_length = new_length - new_length % kCodeCacheEntrySize; 3464 new_length = new_length - new_length % kCodeCacheEntrySize;
3465 Object* result;
3466 { TryAllocation t = cache->CopySize(new_length);
3467 if (!t->ToObject(&result)) return t;
3468 }
3361 ASSERT((new_length % kCodeCacheEntrySize) == 0); 3469 ASSERT((new_length % kCodeCacheEntrySize) == 0);
3362 Object* result = cache->CopySize(new_length);
3363 if (result->IsFailure()) return result;
3364 3470
3365 // Add the (name, code) pair to the new cache. 3471 // Add the (name, code) pair to the new cache.
3366 cache = FixedArray::cast(result); 3472 cache = FixedArray::cast(result);
3367 cache->set(length + kCodeCacheEntryNameOffset, name); 3473 cache->set(length + kCodeCacheEntryNameOffset, name);
3368 cache->set(length + kCodeCacheEntryCodeOffset, code); 3474 cache->set(length + kCodeCacheEntryCodeOffset, code);
3369 set_default_cache(cache); 3475 set_default_cache(cache);
3370 return this; 3476 return this;
3371 } 3477 }
3372 3478
3373 3479
3374 Object* CodeCache::UpdateNormalTypeCache(String* name, Code* code) { 3480 Object* CodeCache::UpdateNormalTypeCache(String* name, Code* code) {
3375 // Adding a new entry can cause a new cache to be allocated. 3481 // Adding a new entry can cause a new cache to be allocated.
3482 Object* new_cache;
3483 { TryAllocation t = cache->Put(name, code);
3484 if (!t->ToObject(&new_cache)) return t;
3485 }
3376 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); 3486 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache());
3377 Object* new_cache = cache->Put(name, code);
3378 if (new_cache->IsFailure()) return new_cache;
3379 set_normal_type_cache(new_cache); 3487 set_normal_type_cache(new_cache);
3380 return this; 3488 return this;
3381 } 3489 }
3382 3490
3383 3491
3384 Object* CodeCache::Lookup(String* name, Code::Flags flags) { 3492 Object* CodeCache::Lookup(String* name, Code::Flags flags) {
3385 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { 3493 if (Code::ExtractTypeFromFlags(flags) == NORMAL) {
3386 return LookupNormalTypeCache(name, flags); 3494 return LookupNormalTypeCache(name, flags);
3387 } else { 3495 } else {
3388 return LookupDefaultCache(name, flags); 3496 return LookupDefaultCache(name, flags);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
3487 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); } 3595 uint32_t Hash() { return NameFlagsHashHelper(name_, flags_); }
3488 3596
3489 uint32_t HashForObject(Object* obj) { 3597 uint32_t HashForObject(Object* obj) {
3490 FixedArray* pair = FixedArray::cast(obj); 3598 FixedArray* pair = FixedArray::cast(obj);
3491 String* name = String::cast(pair->get(0)); 3599 String* name = String::cast(pair->get(0));
3492 Code* code = Code::cast(pair->get(1)); 3600 Code* code = Code::cast(pair->get(1));
3493 return NameFlagsHashHelper(name, code->flags()); 3601 return NameFlagsHashHelper(name, code->flags());
3494 } 3602 }
3495 3603
3496 Object* AsObject() { 3604 Object* AsObject() {
3605 Object* obj;
3606 { TryAllocation t = Heap::AllocateFixedArray(2);
3607 if (!t->ToObject(&obj)) return t;
3608 }
3497 ASSERT(code_ != NULL); 3609 ASSERT(code_ != NULL);
3498 Object* obj = Heap::AllocateFixedArray(2);
3499 if (obj->IsFailure()) return obj;
3500 FixedArray* pair = FixedArray::cast(obj); 3610 FixedArray* pair = FixedArray::cast(obj);
3501 pair->set(0, name_); 3611 pair->set(0, name_);
3502 pair->set(1, code_); 3612 pair->set(1, code_);
3503 return pair; 3613 return pair;
3504 } 3614 }
3505 3615
3506 private: 3616 private:
3507 String* name_; 3617 String* name_;
3508 Code::Flags flags_; 3618 Code::Flags flags_;
3509 Code* code_; 3619 Code* code_;
3510 }; 3620 };
3511 3621
3512 3622
3513 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { 3623 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) {
3514 CodeCacheHashTableKey key(name, flags); 3624 CodeCacheHashTableKey key(name, flags);
3515 int entry = FindEntry(&key); 3625 int entry = FindEntry(&key);
3516 if (entry == kNotFound) return Heap::undefined_value(); 3626 if (entry == kNotFound) return Heap::undefined_value();
3517 return get(EntryToIndex(entry) + 1); 3627 return get(EntryToIndex(entry) + 1);
3518 } 3628 }
3519 3629
3520 3630
3521 Object* CodeCacheHashTable::Put(String* name, Code* code) { 3631 Object* CodeCacheHashTable::Put(String* name, Code* code) {
3632 Object* obj;
3633 { TryAllocation t = EnsureCapacity(1, &key);
3634 if (!t->ToObject(&obj)) return t;
3635 }
3522 CodeCacheHashTableKey key(name, code); 3636 CodeCacheHashTableKey key(name, code);
3523 Object* obj = EnsureCapacity(1, &key);
3524 if (obj->IsFailure()) return obj;
3525 3637
3526 // Don't use this, as the table might have grown. 3638 // Don't use this, as the table might have grown.
3527 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj); 3639 CodeCacheHashTable* cache = reinterpret_cast<CodeCacheHashTable*>(obj);
3528 3640
3641 Object* k;
3642 { TryAllocation t = key.AsObject();
3643 if (!t->ToObject(&k)) return t;
3644 }
3529 int entry = cache->FindInsertionEntry(key.Hash()); 3645 int entry = cache->FindInsertionEntry(key.Hash());
3530 Object* k = key.AsObject();
3531 if (k->IsFailure()) return k;
3532 3646
3533 cache->set(EntryToIndex(entry), k); 3647 cache->set(EntryToIndex(entry), k);
3534 cache->set(EntryToIndex(entry) + 1, code); 3648 cache->set(EntryToIndex(entry) + 1, code);
3535 cache->ElementAdded(); 3649 cache->ElementAdded();
3536 return cache; 3650 return cache;
3537 } 3651 }
3538 3652
3539 3653
3540 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { 3654 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) {
3541 CodeCacheHashTableKey key(name, flags); 3655 CodeCacheHashTableKey key(name, flags);
(...skipping 26 matching lines...) Expand all
3568 3682
3569 Object* FixedArray::AddKeysFromJSArray(JSArray* array) { 3683 Object* FixedArray::AddKeysFromJSArray(JSArray* array) {
3570 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements()); 3684 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements());
3571 switch (array->GetElementsKind()) { 3685 switch (array->GetElementsKind()) {
3572 case JSObject::FAST_ELEMENTS: 3686 case JSObject::FAST_ELEMENTS:
3573 return UnionOfKeys(FixedArray::cast(array->elements())); 3687 return UnionOfKeys(FixedArray::cast(array->elements()));
3574 case JSObject::DICTIONARY_ELEMENTS: { 3688 case JSObject::DICTIONARY_ELEMENTS: {
3575 NumberDictionary* dict = array->element_dictionary(); 3689 NumberDictionary* dict = array->element_dictionary();
3576 int size = dict->NumberOfElements(); 3690 int size = dict->NumberOfElements();
3577 3691
3692 Object* object;
3693 { TryAllocation t = Heap::AllocateFixedArray(size);
3694 if (!t->ToObject(&object)) return t;
3695 }
3578 // Allocate a temporary fixed array. 3696 // Allocate a temporary fixed array.
3579 Object* object = Heap::AllocateFixedArray(size);
3580 if (object->IsFailure()) return object;
3581 FixedArray* key_array = FixedArray::cast(object); 3697 FixedArray* key_array = FixedArray::cast(object);
3582 3698
3583 int capacity = dict->Capacity(); 3699 int capacity = dict->Capacity();
3584 int pos = 0; 3700 int pos = 0;
3585 // Copy the elements from the JSArray to the temporary fixed array. 3701 // Copy the elements from the JSArray to the temporary fixed array.
3586 for (int i = 0; i < capacity; i++) { 3702 for (int i = 0; i < capacity; i++) {
3587 if (dict->IsKey(dict->KeyAt(i))) { 3703 if (dict->IsKey(dict->KeyAt(i))) {
3588 key_array->set(pos++, dict->ValueAt(i)); 3704 key_array->set(pos++, dict->ValueAt(i));
3589 } 3705 }
3590 } 3706 }
(...skipping 17 matching lines...) Expand all
3608 3724
3609 // Compute how many elements are not in this. 3725 // Compute how many elements are not in this.
3610 int extra = 0; 3726 int extra = 0;
3611 for (int y = 0; y < len1; y++) { 3727 for (int y = 0; y < len1; y++) {
3612 Object* value = other->get(y); 3728 Object* value = other->get(y);
3613 if (!value->IsTheHole() && !HasKey(this, value)) extra++; 3729 if (!value->IsTheHole() && !HasKey(this, value)) extra++;
3614 } 3730 }
3615 3731
3616 if (extra == 0) return this; 3732 if (extra == 0) return this;
3617 3733
3734 Object* obj;
3735 { TryAllocation t = Heap::AllocateFixedArray(len0 + extra);
3736 if (!t->ToObject(&obj)) return t;
3737 }
3618 // Allocate the result 3738 // Allocate the result
3619 Object* obj = Heap::AllocateFixedArray(len0 + extra);
3620 if (obj->IsFailure()) return obj;
3621 // Fill in the content 3739 // Fill in the content
3622 AssertNoAllocation no_gc; 3740 AssertNoAllocation no_gc;
3623 FixedArray* result = FixedArray::cast(obj); 3741 FixedArray* result = FixedArray::cast(obj);
3624 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 3742 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3625 for (int i = 0; i < len0; i++) { 3743 for (int i = 0; i < len0; i++) {
3626 result->set(i, get(i), mode); 3744 result->set(i, get(i), mode);
3627 } 3745 }
3628 // Fill in the extra keys. 3746 // Fill in the extra keys.
3629 int index = 0; 3747 int index = 0;
3630 for (int y = 0; y < len1; y++) { 3748 for (int y = 0; y < len1; y++) {
3631 Object* value = other->get(y); 3749 Object* value = other->get(y);
3632 if (!value->IsTheHole() && !HasKey(this, value)) { 3750 if (!value->IsTheHole() && !HasKey(this, value)) {
3633 result->set(len0 + index, other->get(y), mode); 3751 result->set(len0 + index, other->get(y), mode);
3634 index++; 3752 index++;
3635 } 3753 }
3636 } 3754 }
3637 ASSERT(extra == index); 3755 ASSERT(extra == index);
3638 return result; 3756 return result;
3639 } 3757 }
3640 3758
3641 3759
3642 Object* FixedArray::CopySize(int new_length) { 3760 Object* FixedArray::CopySize(int new_length) {
3761 Object* obj;
3762 { TryAllocation t = Heap::AllocateFixedArray(new_length);
3763 if (!t->ToObject(&obj)) return t;
3764 }
3643 if (new_length == 0) return Heap::empty_fixed_array(); 3765 if (new_length == 0) return Heap::empty_fixed_array();
3644 Object* obj = Heap::AllocateFixedArray(new_length);
3645 if (obj->IsFailure()) return obj;
3646 FixedArray* result = FixedArray::cast(obj); 3766 FixedArray* result = FixedArray::cast(obj);
3647 // Copy the content 3767 // Copy the content
3648 AssertNoAllocation no_gc; 3768 AssertNoAllocation no_gc;
3649 int len = length(); 3769 int len = length();
3650 if (new_length < len) len = new_length; 3770 if (new_length < len) len = new_length;
3651 result->set_map(map()); 3771 result->set_map(map());
3652 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 3772 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
3653 for (int i = 0; i < len; i++) { 3773 for (int i = 0; i < len; i++) {
3654 result->set(i, get(i), mode); 3774 result->set(i, get(i), mode);
3655 } 3775 }
(...skipping 19 matching lines...) Expand all
3675 return true; 3795 return true;
3676 } 3796 }
3677 #endif 3797 #endif
3678 3798
3679 3799
3680 Object* DescriptorArray::Allocate(int number_of_descriptors) { 3800 Object* DescriptorArray::Allocate(int number_of_descriptors) {
3681 if (number_of_descriptors == 0) { 3801 if (number_of_descriptors == 0) {
3682 return Heap::empty_descriptor_array(); 3802 return Heap::empty_descriptor_array();
3683 } 3803 }
3684 // Allocate the array of keys. 3804 // Allocate the array of keys.
3685 Object* array = 3805 Object* array;
3686 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); 3806 { TryAllocation t =
3687 if (array->IsFailure()) return array; 3807 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors));
3808 if (!t->ToObject(&array)) return t;
3809 }
3688 // Do not use DescriptorArray::cast on incomplete object. 3810 // Do not use DescriptorArray::cast on incomplete object.
3689 FixedArray* result = FixedArray::cast(array); 3811 FixedArray* result = FixedArray::cast(array);
3690 3812
3813 { TryAllocation t = Heap::AllocateFixedArray(number_of_descriptors << 1);
3814 if (!t->ToObject(&array)) return t;
3815 }
3691 // Allocate the content array and set it in the descriptor array. 3816 // Allocate the content array and set it in the descriptor array.
3692 array = Heap::AllocateFixedArray(number_of_descriptors << 1);
3693 if (array->IsFailure()) return array;
3694 result->set(kContentArrayIndex, array); 3817 result->set(kContentArrayIndex, array);
3695 result->set(kEnumerationIndexIndex, 3818 result->set(kEnumerationIndexIndex,
3696 Smi::FromInt(PropertyDetails::kInitialIndex)); 3819 Smi::FromInt(PropertyDetails::kInitialIndex));
3697 return result; 3820 return result;
3698 } 3821 }
3699 3822
3700 3823
3701 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, 3824 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
3702 FixedArray* new_cache) { 3825 FixedArray* new_cache) {
3703 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); 3826 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
(...skipping 16 matching lines...) Expand all
3720 TransitionFlag transition_flag) { 3843 TransitionFlag transition_flag) {
3721 // Transitions are only kept when inserting another transition. 3844 // Transitions are only kept when inserting another transition.
3722 // This precondition is not required by this function's implementation, but 3845 // This precondition is not required by this function's implementation, but
3723 // is currently required by the semantics of maps, so we check it. 3846 // is currently required by the semantics of maps, so we check it.
3724 // Conversely, we filter after replacing, so replacing a transition and 3847 // Conversely, we filter after replacing, so replacing a transition and
3725 // removing all other transitions is not supported. 3848 // removing all other transitions is not supported.
3726 bool remove_transitions = transition_flag == REMOVE_TRANSITIONS; 3849 bool remove_transitions = transition_flag == REMOVE_TRANSITIONS;
3727 ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition()); 3850 ASSERT(remove_transitions == !descriptor->GetDetails().IsTransition());
3728 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR); 3851 ASSERT(descriptor->GetDetails().type() != NULL_DESCRIPTOR);
3729 3852
3853 Object* result;
3854 { TryAllocation t = descriptor->KeyToSymbol();
3855 if (!t->ToObject(&result)) return t;
3856 }
3730 // Ensure the key is a symbol. 3857 // Ensure the key is a symbol.
3731 Object* result = descriptor->KeyToSymbol();
3732 if (result->IsFailure()) return result;
3733 3858
3734 int transitions = 0; 3859 int transitions = 0;
3735 int null_descriptors = 0; 3860 int null_descriptors = 0;
3736 if (remove_transitions) { 3861 if (remove_transitions) {
3737 for (int i = 0; i < number_of_descriptors(); i++) { 3862 for (int i = 0; i < number_of_descriptors(); i++) {
3738 if (IsTransition(i)) transitions++; 3863 if (IsTransition(i)) transitions++;
3739 if (IsNullDescriptor(i)) null_descriptors++; 3864 if (IsNullDescriptor(i)) null_descriptors++;
3740 } 3865 }
3741 } else { 3866 } else {
3742 for (int i = 0; i < number_of_descriptors(); i++) { 3867 for (int i = 0; i < number_of_descriptors(); i++) {
(...skipping 18 matching lines...) Expand all
3761 if (t == CONSTANT_FUNCTION || 3886 if (t == CONSTANT_FUNCTION ||
3762 t == FIELD || 3887 t == FIELD ||
3763 t == CALLBACKS || 3888 t == CALLBACKS ||
3764 t == INTERCEPTOR) { 3889 t == INTERCEPTOR) {
3765 keep_enumeration_index = true; 3890 keep_enumeration_index = true;
3766 } else if (remove_transitions) { 3891 } else if (remove_transitions) {
3767 // Replaced descriptor has been counted as removed if it is 3892 // Replaced descriptor has been counted as removed if it is
3768 // a transition that will be replaced. Adjust count in this case. 3893 // a transition that will be replaced. Adjust count in this case.
3769 ++new_size; 3894 ++new_size;
3770 } 3895 }
3896 { TryAllocation t = Allocate(new_size);
3897 if (!t->ToObject(&result)) return t;
3771 } 3898 }
3772 result = Allocate(new_size); 3899 }
3773 if (result->IsFailure()) return result;
3774 DescriptorArray* new_descriptors = DescriptorArray::cast(result); 3900 DescriptorArray* new_descriptors = DescriptorArray::cast(result);
3775 // Set the enumeration index in the descriptors and set the enumeration index 3901 // Set the enumeration index in the descriptors and set the enumeration index
3776 // in the result. 3902 // in the result.
3777 int enumeration_index = NextEnumerationIndex(); 3903 int enumeration_index = NextEnumerationIndex();
3778 if (!descriptor->GetDetails().IsTransition()) { 3904 if (!descriptor->GetDetails().IsTransition()) {
3779 if (keep_enumeration_index) { 3905 if (keep_enumeration_index) {
3780 descriptor->SetEnumerationIndex( 3906 descriptor->SetEnumerationIndex(
3781 PropertyDetails(GetDetails(index)).index()); 3907 PropertyDetails(GetDetails(index)).index());
3782 } else { 3908 } else {
3783 descriptor->SetEnumerationIndex(enumeration_index); 3909 descriptor->SetEnumerationIndex(enumeration_index);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3822 // Remove all transitions and null descriptors. Return a copy of the array 3948 // Remove all transitions and null descriptors. Return a copy of the array
3823 // with all transitions removed, or a Failure object if the new array could 3949 // with all transitions removed, or a Failure object if the new array could
3824 // not be allocated. 3950 // not be allocated.
3825 3951
3826 // Compute the size of the map transition entries to be removed. 3952 // Compute the size of the map transition entries to be removed.
3827 int num_removed = 0; 3953 int num_removed = 0;
3828 for (int i = 0; i < number_of_descriptors(); i++) { 3954 for (int i = 0; i < number_of_descriptors(); i++) {
3829 if (!IsProperty(i)) num_removed++; 3955 if (!IsProperty(i)) num_removed++;
3830 } 3956 }
3831 3957
3958 Object* result;
3959 { TryAllocation t = Allocate(number_of_descriptors() - num_removed);
3960 if (!t->ToObject(&result)) return t;
3961 }
3832 // Allocate the new descriptor array. 3962 // Allocate the new descriptor array.
3833 Object* result = Allocate(number_of_descriptors() - num_removed);
3834 if (result->IsFailure()) return result;
3835 DescriptorArray* new_descriptors = DescriptorArray::cast(result); 3963 DescriptorArray* new_descriptors = DescriptorArray::cast(result);
3836 3964
3837 // Copy the content. 3965 // Copy the content.
3838 int next_descriptor = 0; 3966 int next_descriptor = 0;
3839 for (int i = 0; i < number_of_descriptors(); i++) { 3967 for (int i = 0; i < number_of_descriptors(); i++) {
3840 if (IsProperty(i)) new_descriptors->CopyFrom(next_descriptor++, this, i); 3968 if (IsProperty(i)) new_descriptors->CopyFrom(next_descriptor++, this, i);
3841 } 3969 }
3842 ASSERT(next_descriptor == new_descriptors->number_of_descriptors()); 3970 ASSERT(next_descriptor == new_descriptors->number_of_descriptors());
3843 3971
3844 return new_descriptors; 3972 return new_descriptors;
(...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after
5176 ASSERT(should_have_prototype()); 5304 ASSERT(should_have_prototype());
5177 Object* construct_prototype = value; 5305 Object* construct_prototype = value;
5178 5306
5179 // If the value is not a JSObject, store the value in the map's 5307 // If the value is not a JSObject, store the value in the map's
5180 // constructor field so it can be accessed. Also, set the prototype 5308 // constructor field so it can be accessed. Also, set the prototype
5181 // used for constructing objects to the original object prototype. 5309 // used for constructing objects to the original object prototype.
5182 // See ECMA-262 13.2.2. 5310 // See ECMA-262 13.2.2.
5183 if (!value->IsJSObject()) { 5311 if (!value->IsJSObject()) {
5184 // Copy the map so this does not affect unrelated functions. 5312 // Copy the map so this does not affect unrelated functions.
5185 // Remove map transitions because they point to maps with a 5313 // Remove map transitions because they point to maps with a
5314 Object* new_map;
5315 { TryAllocation t = map()->CopyDropTransitions();
5316 if (!t->ToObject(&new_map)) return t;
5317 }
5186 // different prototype. 5318 // different prototype.
5187 Object* new_map = map()->CopyDropTransitions();
5188 if (new_map->IsFailure()) return new_map;
5189 set_map(Map::cast(new_map)); 5319 set_map(Map::cast(new_map));
5190 map()->set_constructor(value); 5320 map()->set_constructor(value);
5191 map()->set_non_instance_prototype(true); 5321 map()->set_non_instance_prototype(true);
5192 construct_prototype = 5322 construct_prototype =
5193 Top::context()->global_context()->initial_object_prototype(); 5323 Top::context()->global_context()->initial_object_prototype();
5194 } else { 5324 } else {
5195 map()->set_non_instance_prototype(false); 5325 map()->set_non_instance_prototype(false);
5196 } 5326 }
5197 5327
5198 return SetInstancePrototype(construct_prototype); 5328 return SetInstancePrototype(construct_prototype);
(...skipping 12 matching lines...) Expand all
5211 shared()->set_instance_class_name(name); 5341 shared()->set_instance_class_name(name);
5212 return this; 5342 return this;
5213 } 5343 }
5214 5344
5215 5345
5216 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { 5346 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) {
5217 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); 5347 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex));
5218 } 5348 }
5219 5349
5220 5350
5351 Object* symbol;
5352 { TryAllocation t = Heap::LookupAsciiSymbol(to_string);
5353 if (!t->ToObject(&symbol)) return t;
5354 }
5221 Object* Oddball::Initialize(const char* to_string, Object* to_number) { 5355 Object* Oddball::Initialize(const char* to_string, Object* to_number) {
5222 Object* symbol = Heap::LookupAsciiSymbol(to_string);
5223 if (symbol->IsFailure()) return symbol;
5224 set_to_string(String::cast(symbol)); 5356 set_to_string(String::cast(symbol));
5225 set_to_number(to_number); 5357 set_to_number(to_number);
5226 return this; 5358 return this;
5227 } 5359 }
5228 5360
5229 5361
5230 bool SharedFunctionInfo::HasSourceCode() { 5362 bool SharedFunctionInfo::HasSourceCode() {
5231 return !script()->IsUndefined() && 5363 return !script()->IsUndefined() &&
5232 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); 5364 !reinterpret_cast<Script*>(script())->source()->IsUndefined();
5233 } 5365 }
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
5698 for (RelocIterator it(this); !it.done(); it.next()) 5830 for (RelocIterator it(this); !it.done(); it.next())
5699 it.rinfo()->Print(); 5831 it.rinfo()->Print();
5700 PrintF("\n"); 5832 PrintF("\n");
5701 } 5833 }
5702 #endif // ENABLE_DISASSEMBLER 5834 #endif // ENABLE_DISASSEMBLER
5703 5835
5704 5836
5705 Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) { 5837 Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) {
5706 // We should never end in here with a pixel or external array. 5838 // We should never end in here with a pixel or external array.
5707 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 5839 ASSERT(!HasPixelElements() && !HasExternalArrayElements());
5840 Object* obj;
5841 { TryAllocation t = Heap::AllocateFixedArrayWithHoles(capacity);
5842 if (!t->ToObject(&obj)) return t;
5843 }
5708 5844
5709 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
5710 if (obj->IsFailure()) return obj;
5711 FixedArray* elems = FixedArray::cast(obj); 5845 FixedArray* elems = FixedArray::cast(obj);
5846 { TryAllocation t = map()->GetFastElementsMap();
5847 if (!t->ToObject(&obj)) return t;
5848 }
5712 5849
5713 obj = map()->GetFastElementsMap();
5714 if (obj->IsFailure()) return obj;
5715 Map* new_map = Map::cast(obj); 5850 Map* new_map = Map::cast(obj);
5716 5851
5717 AssertNoAllocation no_gc; 5852 AssertNoAllocation no_gc;
5718 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); 5853 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
5719 switch (GetElementsKind()) { 5854 switch (GetElementsKind()) {
5720 case FAST_ELEMENTS: { 5855 case FAST_ELEMENTS: {
5721 FixedArray* old_elements = FixedArray::cast(elements()); 5856 FixedArray* old_elements = FixedArray::cast(elements());
5722 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); 5857 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
5723 // Fill out the new array with this content and array holes. 5858 // Fill out the new array with this content and array holes.
5724 for (uint32_t i = 0; i < old_length; i++) { 5859 for (uint32_t i = 0; i < old_length; i++) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
5756 Object* JSObject::SetSlowElements(Object* len) { 5891 Object* JSObject::SetSlowElements(Object* len) {
5757 // We should never end in here with a pixel or external array. 5892 // We should never end in here with a pixel or external array.
5758 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); 5893 ASSERT(!HasPixelElements() && !HasExternalArrayElements());
5759 5894
5760 uint32_t new_length = static_cast<uint32_t>(len->Number()); 5895 uint32_t new_length = static_cast<uint32_t>(len->Number());
5761 5896
5762 switch (GetElementsKind()) { 5897 switch (GetElementsKind()) {
5763 case FAST_ELEMENTS: { 5898 case FAST_ELEMENTS: {
5764 // Make sure we never try to shrink dense arrays into sparse arrays. 5899 // Make sure we never try to shrink dense arrays into sparse arrays.
5765 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= 5900 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <=
5901 Object* obj;
5902 { TryAllocation t = NormalizeElements();
5903 if (!t->ToObject(&obj)) return t;
5904 }
5766 new_length); 5905 new_length);
5767 Object* obj = NormalizeElements();
5768 if (obj->IsFailure()) return obj;
5769 5906
5770 // Update length for JSArrays. 5907 // Update length for JSArrays.
5771 if (IsJSArray()) JSArray::cast(this)->set_length(len); 5908 if (IsJSArray()) JSArray::cast(this)->set_length(len);
5772 break; 5909 break;
5773 } 5910 }
5774 case DICTIONARY_ELEMENTS: { 5911 case DICTIONARY_ELEMENTS: {
5775 if (IsJSArray()) { 5912 if (IsJSArray()) {
5776 uint32_t old_length = 5913 uint32_t old_length =
5777 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); 5914 static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
5778 element_dictionary()->RemoveNumberEntries(new_length, old_length), 5915 element_dictionary()->RemoveNumberEntries(new_length, old_length),
5779 JSArray::cast(this)->set_length(len); 5916 JSArray::cast(this)->set_length(len);
5780 } 5917 }
5781 break; 5918 break;
5782 } 5919 }
5783 default: 5920 default:
5784 UNREACHABLE(); 5921 UNREACHABLE();
5785 break; 5922 break;
5786 } 5923 }
5787 return this; 5924 return this;
5788 } 5925 }
5789 5926
5790 5927
5791 Object* JSArray::Initialize(int capacity) { 5928 Object* JSArray::Initialize(int capacity) {
5792 ASSERT(capacity >= 0); 5929 ASSERT(capacity >= 0);
5793 set_length(Smi::FromInt(0)); 5930 set_length(Smi::FromInt(0));
5794 FixedArray* new_elements; 5931 FixedArray* new_elements;
5795 if (capacity == 0) { 5932 if (capacity == 0) {
5796 new_elements = Heap::empty_fixed_array(); 5933 new_elements = Heap::empty_fixed_array();
5934 Object* obj;
5935 { TryAllocation t = Heap::AllocateFixedArrayWithHoles(capacity);
5936 if (!t->ToObject(&obj)) return t;
5937 }
5797 } else { 5938 } else {
5798 Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
5799 if (obj->IsFailure()) return obj;
5800 new_elements = FixedArray::cast(obj); 5939 new_elements = FixedArray::cast(obj);
5801 } 5940 }
5802 set_elements(new_elements); 5941 set_elements(new_elements);
5803 return this; 5942 return this;
5804 } 5943 }
5805 5944
5806 5945
5807 void JSArray::Expand(int required_size) { 5946 void JSArray::Expand(int required_size) {
5808 Handle<JSArray> self(this); 5947 Handle<JSArray> self(this);
5809 Handle<FixedArray> old_backing(FixedArray::cast(elements())); 5948 Handle<FixedArray> old_backing(FixedArray::cast(elements()));
(...skipping 25 matching lines...) Expand all
5835 ASSERT(AllowsSetElementsLength()); 5974 ASSERT(AllowsSetElementsLength());
5836 5975
5837 Object* smi_length = len->ToSmi(); 5976 Object* smi_length = len->ToSmi();
5838 if (smi_length->IsSmi()) { 5977 if (smi_length->IsSmi()) {
5839 const int value = Smi::cast(smi_length)->value(); 5978 const int value = Smi::cast(smi_length)->value();
5840 if (value < 0) return ArrayLengthRangeError(); 5979 if (value < 0) return ArrayLengthRangeError();
5841 switch (GetElementsKind()) { 5980 switch (GetElementsKind()) {
5842 case FAST_ELEMENTS: { 5981 case FAST_ELEMENTS: {
5843 int old_capacity = FixedArray::cast(elements())->length(); 5982 int old_capacity = FixedArray::cast(elements())->length();
5844 if (value <= old_capacity) { 5983 if (value <= old_capacity) {
5984 Object* obj;
5985 { TryAllocation t = EnsureWritableFastElements();
5986 if (!t->ToObject(&obj)) return t;
5987 }
5845 if (IsJSArray()) { 5988 if (IsJSArray()) {
5846 Object* obj = EnsureWritableFastElements();
5847 if (obj->IsFailure()) return obj;
5848 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); 5989 int old_length = FastD2I(JSArray::cast(this)->length()->Number());
5849 // NOTE: We may be able to optimize this by removing the 5990 // NOTE: We may be able to optimize this by removing the
5850 // last part of the elements backing storage array and 5991 // last part of the elements backing storage array and
5851 // setting the capacity to the new size. 5992 // setting the capacity to the new size.
5852 for (int i = value; i < old_length; i++) { 5993 for (int i = value; i < old_length; i++) {
5853 FixedArray::cast(elements())->set_the_hole(i); 5994 FixedArray::cast(elements())->set_the_hole(i);
5854 } 5995 }
5855 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 5996 JSArray::cast(this)->set_length(Smi::cast(smi_length));
5856 } 5997 }
5857 return this; 5998 return this;
5858 } 5999 }
5859 int min = NewElementsCapacity(old_capacity); 6000 int min = NewElementsCapacity(old_capacity);
5860 int new_capacity = value > min ? value : min; 6001 int new_capacity = value > min ? value : min;
5861 if (new_capacity <= kMaxFastElementsLength || 6002 if (new_capacity <= kMaxFastElementsLength ||
6003 Object* obj;
6004 { TryAllocation t =
6005 SetFastElementsCapacityAndLength(new_capacity, value);
6006 if (!t->ToObject(&obj)) return t;
6007 }
5862 !ShouldConvertToSlowElements(new_capacity)) { 6008 !ShouldConvertToSlowElements(new_capacity)) {
5863 Object* obj = SetFastElementsCapacityAndLength(new_capacity, value);
5864 if (obj->IsFailure()) return obj;
5865 return this; 6009 return this;
5866 } 6010 }
5867 break; 6011 break;
5868 } 6012 }
5869 case DICTIONARY_ELEMENTS: { 6013 case DICTIONARY_ELEMENTS: {
5870 if (IsJSArray()) { 6014 if (IsJSArray()) {
5871 if (value == 0) { 6015 if (value == 0) {
5872 // If the length of a slow array is reset to zero, we clear 6016 // If the length of a slow array is reset to zero, we clear
5873 // the array and flush backing storage. This has the added 6017 // the array and flush backing storage. This has the added
6018 Object* obj;
6019 { TryAllocation t = ResetElements();
6020 if (!t->ToObject(&obj)) return t;
6021 }
5874 // benefit that the array returns to fast mode. 6022 // benefit that the array returns to fast mode.
5875 Object* obj = ResetElements();
5876 if (obj->IsFailure()) return obj;
5877 } else { 6023 } else {
5878 // Remove deleted elements. 6024 // Remove deleted elements.
5879 uint32_t old_length = 6025 uint32_t old_length =
5880 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); 6026 static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
5881 element_dictionary()->RemoveNumberEntries(value, old_length); 6027 element_dictionary()->RemoveNumberEntries(value, old_length);
5882 } 6028 }
5883 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 6029 JSArray::cast(this)->set_length(Smi::cast(smi_length));
5884 } 6030 }
5885 return this; 6031 return this;
5886 } 6032 }
5887 default: 6033 default:
5888 UNREACHABLE(); 6034 UNREACHABLE();
5889 break; 6035 break;
5890 } 6036 }
5891 } 6037 }
5892 6038
5893 // General slow case. 6039 // General slow case.
5894 if (len->IsNumber()) { 6040 if (len->IsNumber()) {
5895 uint32_t length; 6041 uint32_t length;
5896 if (len->ToArrayIndex(&length)) { 6042 if (len->ToArrayIndex(&length)) {
5897 return SetSlowElements(len); 6043 return SetSlowElements(len);
5898 } else { 6044 } else {
5899 return ArrayLengthRangeError(); 6045 return ArrayLengthRangeError();
5900 } 6046 }
5901 } 6047 }
5902 6048
5903 // len is not a number so make the array size one and 6049 // len is not a number so make the array size one and
6050 Object* obj;
6051 { TryAllocation t = Heap::AllocateFixedArray(1);
6052 if (!t->ToObject(&obj)) return t;
6053 }
5904 // set only element to len. 6054 // set only element to len.
5905 Object* obj = Heap::AllocateFixedArray(1);
5906 if (obj->IsFailure()) return obj;
5907 FixedArray::cast(obj)->set(0, len); 6055 FixedArray::cast(obj)->set(0, len);
5908 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); 6056 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
5909 set_elements(FixedArray::cast(obj)); 6057 set_elements(FixedArray::cast(obj));
5910 return this; 6058 return this;
5911 } 6059 }
5912 6060
5913 6061
5914 Object* JSObject::SetPrototype(Object* value, 6062 Object* JSObject::SetPrototype(Object* value,
5915 bool skip_hidden_prototypes) { 6063 bool skip_hidden_prototypes) {
5916 // Silently ignore the change if value is not a JSObject or null. 6064 // Silently ignore the change if value is not a JSObject or null.
(...skipping 19 matching lines...) Expand all
5936 // Find the first object in the chain whose prototype object is not 6084 // Find the first object in the chain whose prototype object is not
5937 // hidden and set the new prototype on that object. 6085 // hidden and set the new prototype on that object.
5938 Object* current_proto = real_receiver->GetPrototype(); 6086 Object* current_proto = real_receiver->GetPrototype();
5939 while (current_proto->IsJSObject() && 6087 while (current_proto->IsJSObject() &&
5940 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { 6088 JSObject::cast(current_proto)->map()->is_hidden_prototype()) {
5941 real_receiver = JSObject::cast(current_proto); 6089 real_receiver = JSObject::cast(current_proto);
5942 current_proto = current_proto->GetPrototype(); 6090 current_proto = current_proto->GetPrototype();
5943 } 6091 }
5944 } 6092 }
5945 6093
6094 Object* new_map;
6095 { TryAllocation t = real_receiver->map()->CopyDropTransitions();
6096 if (!t->ToObject(&new_map)) return t;
6097 }
5946 // Set the new prototype of the object. 6098 // Set the new prototype of the object.
5947 Object* new_map = real_receiver->map()->CopyDropTransitions();
5948 if (new_map->IsFailure()) return new_map;
5949 Map::cast(new_map)->set_prototype(value); 6099 Map::cast(new_map)->set_prototype(value);
5950 real_receiver->set_map(Map::cast(new_map)); 6100 real_receiver->set_map(Map::cast(new_map));
5951 6101
5952 Heap::ClearInstanceofCache(); 6102 Heap::ClearInstanceofCache();
5953 6103
5954 return value; 6104 return value;
5955 } 6105 }
5956 6106
5957 6107
5958 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { 6108 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
6308 UNREACHABLE(); 6458 UNREACHABLE();
6309 return NULL; 6459 return NULL;
6310 } 6460 }
6311 6461
6312 6462
6313 // Adding n elements in fast case is O(n*n). 6463 // Adding n elements in fast case is O(n*n).
6314 // Note: revisit design to have dual undefined values to capture absent 6464 // Note: revisit design to have dual undefined values to capture absent
6315 // elements. 6465 // elements.
6316 Object* JSObject::SetFastElement(uint32_t index, Object* value) { 6466 Object* JSObject::SetFastElement(uint32_t index, Object* value) {
6317 ASSERT(HasFastElements()); 6467 ASSERT(HasFastElements());
6468 Object* elms_obj;
6469 { TryAllocation t = EnsureWritableFastElements();
6470 if (!t->ToObject(&elms_obj)) return t;
6471 }
6318 6472
6319 Object* elms_obj = EnsureWritableFastElements();
6320 if (elms_obj->IsFailure()) return elms_obj;
6321 FixedArray* elms = FixedArray::cast(elms_obj); 6473 FixedArray* elms = FixedArray::cast(elms_obj);
6322 uint32_t elms_length = static_cast<uint32_t>(elms->length()); 6474 uint32_t elms_length = static_cast<uint32_t>(elms->length());
6323 6475
6324 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) { 6476 if (!IsJSArray() && (index >= elms_length || elms->get(index)->IsTheHole())) {
6325 if (SetElementWithCallbackSetterInPrototypes(index, value)) { 6477 if (SetElementWithCallbackSetterInPrototypes(index, value)) {
6326 return value; 6478 return value;
6327 } 6479 }
6328 } 6480 }
6329 6481
6330 // Check whether there is extra space in fixed array.. 6482 // Check whether there is extra space in fixed array..
6331 if (index < elms_length) { 6483 if (index < elms_length) {
6332 elms->set(index, value); 6484 elms->set(index, value);
6333 if (IsJSArray()) { 6485 if (IsJSArray()) {
6334 // Update the length of the array if needed. 6486 // Update the length of the array if needed.
6335 uint32_t array_length = 0; 6487 uint32_t array_length = 0;
6336 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 6488 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
6337 if (index >= array_length) { 6489 if (index >= array_length) {
6338 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 6490 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
6339 } 6491 }
6340 } 6492 }
6341 return value; 6493 return value;
6342 } 6494 }
6343 6495
6344 // Allow gap in fast case. 6496 // Allow gap in fast case.
6345 if ((index - elms_length) < kMaxGap) { 6497 if ((index - elms_length) < kMaxGap) {
6346 // Try allocating extra space. 6498 // Try allocating extra space.
6347 int new_capacity = NewElementsCapacity(index+1); 6499 int new_capacity = NewElementsCapacity(index+1);
6348 if (new_capacity <= kMaxFastElementsLength || 6500 if (new_capacity <= kMaxFastElementsLength ||
6349 !ShouldConvertToSlowElements(new_capacity)) { 6501 !ShouldConvertToSlowElements(new_capacity)) {
6502 Object* obj;
6503 { TryAllocation t =
6504 SetFastElementsCapacityAndLength(new_capacity, index + 1);
6505 if (!t->ToObject(&obj)) return t;
6506 }
6350 ASSERT(static_cast<uint32_t>(new_capacity) > index); 6507 ASSERT(static_cast<uint32_t>(new_capacity) > index);
6351 Object* obj = SetFastElementsCapacityAndLength(new_capacity, index + 1);
6352 if (obj->IsFailure()) return obj;
6353 FixedArray::cast(elements())->set(index, value); 6508 FixedArray::cast(elements())->set(index, value);
6354 return value; 6509 return value;
6355 } 6510 }
6356 } 6511 }
6357 6512
6513 Object* obj;
6514 { TryAllocation t = NormalizeElements();
6515 if (!t->ToObject(&obj)) return t;
6516 }
6358 // Otherwise default to slow case. 6517 // Otherwise default to slow case.
6359 Object* obj = NormalizeElements();
6360 if (obj->IsFailure()) return obj;
6361 ASSERT(HasDictionaryElements()); 6518 ASSERT(HasDictionaryElements());
6362 return SetElement(index, value); 6519 return SetElement(index, value);
6363 } 6520 }
6364 6521
6365 6522
6366 Object* JSObject::SetElement(uint32_t index, Object* value) { 6523 Object* JSObject::SetElement(uint32_t index, Object* value) {
6367 // Check access rights if needed. 6524 // Check access rights if needed.
6368 if (IsAccessCheckNeeded() && 6525 if (IsAccessCheckNeeded() &&
6369 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { 6526 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) {
6370 HandleScope scope; 6527 HandleScope scope;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6452 } 6609 }
6453 } 6610 }
6454 // When we set the is_extensible flag to false we always force 6611 // When we set the is_extensible flag to false we always force
6455 // the element into dictionary mode (and force them to stay there). 6612 // the element into dictionary mode (and force them to stay there).
6456 if (!map()->is_extensible()) { 6613 if (!map()->is_extensible()) {
6457 Handle<Object> number(Heap::NumberFromUint32(index)); 6614 Handle<Object> number(Heap::NumberFromUint32(index));
6458 Handle<String> index_string(Factory::NumberToString(number)); 6615 Handle<String> index_string(Factory::NumberToString(number));
6459 Handle<Object> args[1] = { index_string }; 6616 Handle<Object> args[1] = { index_string };
6460 return Top::Throw(*Factory::NewTypeError("object_not_extensible", 6617 return Top::Throw(*Factory::NewTypeError("object_not_extensible",
6461 HandleVector(args, 1))); 6618 HandleVector(args, 1)));
6619 Object* result;
6620 { TryAllocation t = dictionary->AtNumberPut(index, value);
6621 if (!t->ToObject(&result)) return t;
6462 } 6622 }
6463 Object* result = dictionary->AtNumberPut(index, value); 6623 }
6464 if (result->IsFailure()) return result;
6465 if (elms != FixedArray::cast(result)) { 6624 if (elms != FixedArray::cast(result)) {
6466 set_elements(FixedArray::cast(result)); 6625 set_elements(FixedArray::cast(result));
6467 } 6626 }
6468 } 6627 }
6469 6628
6470 // Update the array length if this JSObject is an array. 6629 // Update the array length if this JSObject is an array.
6471 if (IsJSArray()) { 6630 if (IsJSArray()) {
6472 JSArray* array = JSArray::cast(this); 6631 JSArray* array = JSArray::cast(this);
6473 Object* return_value = array->JSArrayUpdateLengthFromIndex(index, 6632 Object* return_value;
6474 value); 6633 { TryAllocation t = array->JSArrayUpdateLengthFromIndex(index,
6475 if (return_value->IsFailure()) return return_value; 6634 value);
6635 if (!t->ToObject(&return_value)) return t;
6636 }
6476 } 6637 }
6477 6638
6478 // Attempt to put this object back in fast case. 6639 // Attempt to put this object back in fast case.
6479 if (ShouldConvertToFastElements()) { 6640 if (ShouldConvertToFastElements()) {
6480 uint32_t new_length = 0; 6641 uint32_t new_length = 0;
6481 if (IsJSArray()) { 6642 if (IsJSArray()) {
6482 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 6643 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
6483 } else { 6644 } else {
6484 new_length = NumberDictionary::cast(elements())->max_number_key() + 1; 6645 new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
6646 Object* obj;
6647 { TryAllocation t =
6648 SetFastElementsCapacityAndLength(new_length, new_length);
6649 if (!t->ToObject(&obj)) return t;
6485 } 6650 }
6486 Object* obj = SetFastElementsCapacityAndLength(new_length, new_length); 6651 }
6487 if (obj->IsFailure()) return obj;
6488 #ifdef DEBUG 6652 #ifdef DEBUG
6489 if (FLAG_trace_normalization) { 6653 if (FLAG_trace_normalization) {
6490 PrintF("Object elements are fast case again:\n"); 6654 PrintF("Object elements are fast case again:\n");
6491 Print(); 6655 Print();
6492 } 6656 }
6493 #endif 6657 #endif
6494 } 6658 }
6495 6659
6496 return value; 6660 return value;
6497 } 6661 }
6498 default: 6662 default:
6499 UNREACHABLE(); 6663 UNREACHABLE();
6500 break; 6664 break;
6501 } 6665 }
6502 // All possible cases have been handled above. Add a return to avoid the 6666 // All possible cases have been handled above. Add a return to avoid the
6503 // complaints from the compiler. 6667 // complaints from the compiler.
6504 UNREACHABLE(); 6668 UNREACHABLE();
6505 return Heap::null_value(); 6669 return Heap::null_value();
6506 } 6670 }
6507 6671
6508 6672
6509 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) { 6673 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) {
6510 uint32_t old_len = 0; 6674 uint32_t old_len = 0;
6511 CHECK(length()->ToArrayIndex(&old_len)); 6675 CHECK(length()->ToArrayIndex(&old_len));
6512 // Check to see if we need to update the length. For now, we make 6676 // Check to see if we need to update the length. For now, we make
6513 // sure that the length stays within 32-bits (unsigned). 6677 // sure that the length stays within 32-bits (unsigned).
6514 if (index >= old_len && index != 0xffffffff) { 6678 if (index >= old_len && index != 0xffffffff) {
6515 Object* len = 6679 Object* len;
6516 Heap::NumberFromDouble(static_cast<double>(index) + 1); 6680 { TryAllocation t =
6517 if (len->IsFailure()) return len; 6681 Heap::NumberFromDouble(static_cast<double>(index) + 1);
6682 if (!t->ToObject(&len)) return t;
6683 }
6518 set_length(len); 6684 set_length(len);
6519 } 6685 }
6520 return value; 6686 return value;
6521 } 6687 }
6522 6688
6523 6689
6524 Object* JSObject::GetElementPostInterceptor(JSObject* receiver, 6690 Object* JSObject::GetElementPostInterceptor(JSObject* receiver,
6525 uint32_t index) { 6691 uint32_t index) {
6526 // Get element works for both JSObject and JSArray since 6692 // Get element works for both JSObject and JSArray since
6527 // JSArray::length cannot change. 6693 // JSArray::length cannot change.
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after
7367 return StringSharedHashHelper(source_, shared_); 7533 return StringSharedHashHelper(source_, shared_);
7368 } 7534 }
7369 7535
7370 uint32_t HashForObject(Object* obj) { 7536 uint32_t HashForObject(Object* obj) {
7371 FixedArray* pair = FixedArray::cast(obj); 7537 FixedArray* pair = FixedArray::cast(obj);
7372 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); 7538 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0));
7373 String* source = String::cast(pair->get(1)); 7539 String* source = String::cast(pair->get(1));
7374 return StringSharedHashHelper(source, shared); 7540 return StringSharedHashHelper(source, shared);
7375 } 7541 }
7376 7542
7543 Object* obj;
7544 { TryAllocation t = Heap::AllocateFixedArray(2);
7545 if (!t->ToObject(&obj)) return t;
7546 }
7377 Object* AsObject() { 7547 Object* AsObject() {
7378 Object* obj = Heap::AllocateFixedArray(2);
7379 if (obj->IsFailure()) return obj;
7380 FixedArray* pair = FixedArray::cast(obj); 7548 FixedArray* pair = FixedArray::cast(obj);
7381 pair->set(0, shared_); 7549 pair->set(0, shared_);
7382 pair->set(1, source_); 7550 pair->set(1, source_);
7383 return pair; 7551 return pair;
7384 } 7552 }
7385 7553
7386 private: 7554 private:
7387 String* source_; 7555 String* source_;
7388 SharedFunctionInfo* shared_; 7556 SharedFunctionInfo* shared_;
7389 }; 7557 };
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
7606 // Return if: 7774 // Return if:
7607 // 50% is still free after adding n elements and 7775 // 50% is still free after adding n elements and
7608 // at most 50% of the free elements are deleted elements. 7776 // at most 50% of the free elements are deleted elements.
7609 if (nod <= (capacity - nof) >> 1) { 7777 if (nod <= (capacity - nof) >> 1) {
7610 int needed_free = nof >> 1; 7778 int needed_free = nof >> 1;
7611 if (nof + needed_free <= capacity) return this; 7779 if (nof + needed_free <= capacity) return this;
7612 } 7780 }
7613 7781
7614 const int kMinCapacityForPretenure = 256; 7782 const int kMinCapacityForPretenure = 256;
7615 bool pretenure = 7783 bool pretenure =
7784 Object* obj;
7785 { TryAllocation t = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
7786 if (!t->ToObject(&obj)) return t;
7787 }
7616 (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this); 7788 (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this);
7617 Object* obj = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED);
7618 if (obj->IsFailure()) return obj;
7619 7789
7620 AssertNoAllocation no_gc; 7790 AssertNoAllocation no_gc;
7621 HashTable* table = HashTable::cast(obj); 7791 HashTable* table = HashTable::cast(obj);
7622 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); 7792 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc);
7623 7793
7624 // Copy prefix to new array. 7794 // Copy prefix to new array.
7625 for (int i = kPrefixStartIndex; 7795 for (int i = kPrefixStartIndex;
7626 i < kPrefixStartIndex + Shape::kPrefixSize; 7796 i < kPrefixStartIndex + Shape::kPrefixSize;
7627 i++) { 7797 i++) {
7628 table->set(i, get(i), mode); 7798 table->set(i, get(i), mode);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
7742 // Collates undefined and unexisting elements below limit from position 7912 // Collates undefined and unexisting elements below limit from position
7743 // zero of the elements. The object stays in Dictionary mode. 7913 // zero of the elements. The object stays in Dictionary mode.
7744 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 7914 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
7745 ASSERT(HasDictionaryElements()); 7915 ASSERT(HasDictionaryElements());
7746 // Must stay in dictionary mode, either because of requires_slow_elements, 7916 // Must stay in dictionary mode, either because of requires_slow_elements,
7747 // or because we are not going to sort (and therefore compact) all of the 7917 // or because we are not going to sort (and therefore compact) all of the
7748 // elements. 7918 // elements.
7749 NumberDictionary* dict = element_dictionary(); 7919 NumberDictionary* dict = element_dictionary();
7750 HeapNumber* result_double = NULL; 7920 HeapNumber* result_double = NULL;
7751 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 7921 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
7922 Object* new_double;
7923 { TryAllocation t = Heap::AllocateHeapNumber(0.0);
7924 if (!t->ToObject(&new_double)) return t;
7925 }
7752 // Allocate space for result before we start mutating the object. 7926 // Allocate space for result before we start mutating the object.
7753 Object* new_double = Heap::AllocateHeapNumber(0.0);
7754 if (new_double->IsFailure()) return new_double;
7755 result_double = HeapNumber::cast(new_double); 7927 result_double = HeapNumber::cast(new_double);
7756 } 7928 }
7929 Object* obj;
7930 { TryAllocation t = NumberDictionary::Allocate(dict->NumberOfElements());
7931 if (!t->ToObject(&obj)) return t;
7932 }
7757 7933
7758 Object* obj = NumberDictionary::Allocate(dict->NumberOfElements());
7759 if (obj->IsFailure()) return obj;
7760 NumberDictionary* new_dict = NumberDictionary::cast(obj); 7934 NumberDictionary* new_dict = NumberDictionary::cast(obj);
7761 7935
7762 AssertNoAllocation no_alloc; 7936 AssertNoAllocation no_alloc;
7763 7937
7764 uint32_t pos = 0; 7938 uint32_t pos = 0;
7765 uint32_t undefs = 0; 7939 uint32_t undefs = 0;
7766 int capacity = dict->Capacity(); 7940 int capacity = dict->Capacity();
7767 for (int i = 0; i < capacity; i++) { 7941 for (int i = 0; i < capacity; i++) {
7768 Object* k = dict->KeyAt(i); 7942 Object* k = dict->KeyAt(i);
7769 if (dict->IsKey(k)) { 7943 if (dict->IsKey(k)) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
7820 7994
7821 if (HasDictionaryElements()) { 7995 if (HasDictionaryElements()) {
7822 // Convert to fast elements containing only the existing properties. 7996 // Convert to fast elements containing only the existing properties.
7823 // Ordering is irrelevant, since we are going to sort anyway. 7997 // Ordering is irrelevant, since we are going to sort anyway.
7824 NumberDictionary* dict = element_dictionary(); 7998 NumberDictionary* dict = element_dictionary();
7825 if (IsJSArray() || dict->requires_slow_elements() || 7999 if (IsJSArray() || dict->requires_slow_elements() ||
7826 dict->max_number_key() >= limit) { 8000 dict->max_number_key() >= limit) {
7827 return PrepareSlowElementsForSort(limit); 8001 return PrepareSlowElementsForSort(limit);
7828 } 8002 }
7829 // Convert to fast elements. 8003 // Convert to fast elements.
8004 Object* obj;
8005 { TryAllocation t = map()->GetFastElementsMap();
8006 if (!t->ToObject(&obj)) return t;
8007 }
7830 8008
7831 Object* obj = map()->GetFastElementsMap();
7832 if (obj->IsFailure()) return obj;
7833 Map* new_map = Map::cast(obj); 8009 Map* new_map = Map::cast(obj);
7834 8010
7835 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; 8011 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED;
7836 Object* new_array = 8012 Object* new_array;
7837 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); 8013 { TryAllocation t =
7838 if (new_array->IsFailure()) return new_array; 8014 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure);
8015 if (!t->ToObject(&new_array)) return t;
8016 }
7839 FixedArray* fast_elements = FixedArray::cast(new_array); 8017 FixedArray* fast_elements = FixedArray::cast(new_array);
7840 dict->CopyValuesTo(fast_elements); 8018 dict->CopyValuesTo(fast_elements);
7841 8019
7842 set_map(new_map); 8020 set_map(new_map);
7843 set_elements(fast_elements); 8021 set_elements(fast_elements);
8022 Object* obj;
8023 { TryAllocation t = EnsureWritableFastElements();
8024 if (!t->ToObject(&obj)) return t;
8025 }
7844 } else { 8026 } else {
7845 Object* obj = EnsureWritableFastElements();
7846 if (obj->IsFailure()) return obj;
7847 } 8027 }
7848 ASSERT(HasFastElements()); 8028 ASSERT(HasFastElements());
7849 8029
7850 // Collect holes at the end, undefined before that and the rest at the 8030 // Collect holes at the end, undefined before that and the rest at the
7851 // start, and return the number of non-hole, non-undefined values. 8031 // start, and return the number of non-hole, non-undefined values.
7852 8032
7853 FixedArray* elements = FixedArray::cast(this->elements()); 8033 FixedArray* elements = FixedArray::cast(this->elements());
7854 uint32_t elements_length = static_cast<uint32_t>(elements->length()); 8034 uint32_t elements_length = static_cast<uint32_t>(elements->length());
7855 if (limit > elements_length) { 8035 if (limit > elements_length) {
7856 limit = elements_length ; 8036 limit = elements_length ;
7857 } 8037 }
7858 if (limit == 0) { 8038 if (limit == 0) {
7859 return Smi::FromInt(0); 8039 return Smi::FromInt(0);
7860 } 8040 }
7861 8041
7862 HeapNumber* result_double = NULL; 8042 HeapNumber* result_double = NULL;
7863 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 8043 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
7864 // Pessimistically allocate space for return value before 8044 // Pessimistically allocate space for return value before
8045 Object* new_double;
8046 { TryAllocation t = Heap::AllocateHeapNumber(0.0);
8047 if (!t->ToObject(&new_double)) return t;
8048 }
7865 // we start mutating the array. 8049 // we start mutating the array.
7866 Object* new_double = Heap::AllocateHeapNumber(0.0);
7867 if (new_double->IsFailure()) return new_double;
7868 result_double = HeapNumber::cast(new_double); 8050 result_double = HeapNumber::cast(new_double);
7869 } 8051 }
7870 8052
7871 AssertNoAllocation no_alloc; 8053 AssertNoAllocation no_alloc;
7872 8054
7873 // Split elements into defined, undefined and the_hole, in that order. 8055 // Split elements into defined, undefined and the_hole, in that order.
7874 // Only count locations for undefined and the hole, and fill them afterwards. 8056 // Only count locations for undefined and the hole, and fill them afterwards.
7875 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); 8057 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
7876 unsigned int undefs = limit; 8058 unsigned int undefs = limit;
7877 unsigned int holes = limit; 8059 unsigned int holes = limit;
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
8052 ASSERT(!HasFastProperties()); 8234 ASSERT(!HasFastProperties());
8053 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); 8235 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry());
8054 ASSERT(value->IsJSGlobalPropertyCell()); 8236 ASSERT(value->IsJSGlobalPropertyCell());
8055 return value; 8237 return value;
8056 } 8238 }
8057 8239
8058 8240
8059 Object* GlobalObject::EnsurePropertyCell(String* name) { 8241 Object* GlobalObject::EnsurePropertyCell(String* name) {
8060 ASSERT(!HasFastProperties()); 8242 ASSERT(!HasFastProperties());
8061 int entry = property_dictionary()->FindEntry(name); 8243 int entry = property_dictionary()->FindEntry(name);
8244 Object* cell;
8245 { TryAllocation t =
8246 Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value());
8247 if (!t->ToObject(&cell)) return t;
8248 }
8062 if (entry == StringDictionary::kNotFound) { 8249 if (entry == StringDictionary::kNotFound) {
8063 Object* cell = Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value());
8064 if (cell->IsFailure()) return cell;
8065 PropertyDetails details(NONE, NORMAL); 8250 PropertyDetails details(NONE, NORMAL);
8251 Object* dictionary;
8252 { TryAllocation t = property_dictionary()->Add(name, cell, details);
8253 if (!t->ToObject(&dictionary)) return t;
8254 }
8066 details = details.AsDeleted(); 8255 details = details.AsDeleted();
8067 Object* dictionary = property_dictionary()->Add(name, cell, details);
8068 if (dictionary->IsFailure()) return dictionary;
8069 set_properties(StringDictionary::cast(dictionary)); 8256 set_properties(StringDictionary::cast(dictionary));
8070 return cell; 8257 return cell;
8071 } else { 8258 } else {
8072 Object* value = property_dictionary()->ValueAt(entry); 8259 Object* value = property_dictionary()->ValueAt(entry);
8073 ASSERT(value->IsJSGlobalPropertyCell()); 8260 ASSERT(value->IsJSGlobalPropertyCell());
8074 return value; 8261 return value;
8075 } 8262 }
8076 } 8263 }
8077 8264
8078 8265
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
8181 8368
8182 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) { 8369 Object* SymbolTable::LookupKey(HashTableKey* key, Object** s) {
8183 int entry = FindEntry(key); 8370 int entry = FindEntry(key);
8184 8371
8185 // Symbol already in table. 8372 // Symbol already in table.
8186 if (entry != kNotFound) { 8373 if (entry != kNotFound) {
8187 *s = KeyAt(entry); 8374 *s = KeyAt(entry);
8188 return this; 8375 return this;
8189 } 8376 }
8190 8377
8378 Object* obj;
8379 { TryAllocation t = EnsureCapacity(1, key);
8380 if (!t->ToObject(&obj)) return t;
8381 }
8191 // Adding new symbol. Grow table if needed. 8382 // Adding new symbol. Grow table if needed.
8192 Object* obj = EnsureCapacity(1, key);
8193 if (obj->IsFailure()) return obj;
8194 8383
8384 Object* symbol;
8385 { TryAllocation t = key->AsObject();
8386 if (!t->ToObject(&symbol)) return t;
8387 }
8195 // Create symbol object. 8388 // Create symbol object.
8196 Object* symbol = key->AsObject();
8197 if (symbol->IsFailure()) return symbol;
8198 8389
8199 // If the symbol table grew as part of EnsureCapacity, obj is not 8390 // If the symbol table grew as part of EnsureCapacity, obj is not
8200 // the current symbol table and therefore we cannot use 8391 // the current symbol table and therefore we cannot use
8201 // SymbolTable::cast here. 8392 // SymbolTable::cast here.
8202 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj); 8393 SymbolTable* table = reinterpret_cast<SymbolTable*>(obj);
8203 8394
8204 // Add the new symbol and return it along with the symbol table. 8395 // Add the new symbol and return it along with the symbol table.
8205 entry = table->FindInsertionEntry(key->Hash()); 8396 entry = table->FindInsertionEntry(key->Hash());
8206 table->set(EntryToIndex(entry), symbol); 8397 table->set(EntryToIndex(entry), symbol);
8207 table->ElementAdded(); 8398 table->ElementAdded();
(...skipping 21 matching lines...) Expand all
8229 Object* CompilationCacheTable::LookupRegExp(String* src, 8420 Object* CompilationCacheTable::LookupRegExp(String* src,
8230 JSRegExp::Flags flags) { 8421 JSRegExp::Flags flags) {
8231 RegExpKey key(src, flags); 8422 RegExpKey key(src, flags);
8232 int entry = FindEntry(&key); 8423 int entry = FindEntry(&key);
8233 if (entry == kNotFound) return Heap::undefined_value(); 8424 if (entry == kNotFound) return Heap::undefined_value();
8234 return get(EntryToIndex(entry) + 1); 8425 return get(EntryToIndex(entry) + 1);
8235 } 8426 }
8236 8427
8237 8428
8238 Object* CompilationCacheTable::Put(String* src, Object* value) { 8429 Object* CompilationCacheTable::Put(String* src, Object* value) {
8430 Object* obj;
8431 { TryAllocation t = EnsureCapacity(1, &key);
8432 if (!t->ToObject(&obj)) return t;
8433 }
8239 StringKey key(src); 8434 StringKey key(src);
8240 Object* obj = EnsureCapacity(1, &key);
8241 if (obj->IsFailure()) return obj;
8242 8435
8243 CompilationCacheTable* cache = 8436 CompilationCacheTable* cache =
8244 reinterpret_cast<CompilationCacheTable*>(obj); 8437 reinterpret_cast<CompilationCacheTable*>(obj);
8245 int entry = cache->FindInsertionEntry(key.Hash()); 8438 int entry = cache->FindInsertionEntry(key.Hash());
8246 cache->set(EntryToIndex(entry), src); 8439 cache->set(EntryToIndex(entry), src);
8247 cache->set(EntryToIndex(entry) + 1, value); 8440 cache->set(EntryToIndex(entry) + 1, value);
8248 cache->ElementAdded(); 8441 cache->ElementAdded();
8249 return cache; 8442 return cache;
8250 } 8443 }
8251 8444
8252 8445
8253 Object* CompilationCacheTable::PutEval(String* src, 8446 Object* CompilationCacheTable::PutEval(String* src,
8254 Context* context, 8447 Context* context,
8255 Object* value) { 8448 Object* value) {
8449 Object* obj;
8450 { TryAllocation t = EnsureCapacity(1, &key);
8451 if (!t->ToObject(&obj)) return t;
8452 }
8256 StringSharedKey key(src, context->closure()->shared()); 8453 StringSharedKey key(src, context->closure()->shared());
8257 Object* obj = EnsureCapacity(1, &key);
8258 if (obj->IsFailure()) return obj;
8259 8454
8260 CompilationCacheTable* cache = 8455 CompilationCacheTable* cache =
8261 reinterpret_cast<CompilationCacheTable*>(obj); 8456 reinterpret_cast<CompilationCacheTable*>(obj);
8262 int entry = cache->FindInsertionEntry(key.Hash()); 8457 int entry = cache->FindInsertionEntry(key.Hash());
8458 Object* k;
8459 { TryAllocation t = key.AsObject();
8460 if (!t->ToObject(&k)) return t;
8461 }
8263 8462
8264 Object* k = key.AsObject();
8265 if (k->IsFailure()) return k;
8266 8463
8267 cache->set(EntryToIndex(entry), k); 8464 cache->set(EntryToIndex(entry), k);
8268 cache->set(EntryToIndex(entry) + 1, value); 8465 cache->set(EntryToIndex(entry) + 1, value);
8269 cache->ElementAdded(); 8466 cache->ElementAdded();
8270 return cache; 8467 return cache;
8271 } 8468 }
8272 8469
8273 8470
8274 Object* CompilationCacheTable::PutRegExp(String* src, 8471 Object* CompilationCacheTable::PutRegExp(String* src,
8275 JSRegExp::Flags flags, 8472 JSRegExp::Flags flags,
8276 FixedArray* value) { 8473 FixedArray* value) {
8474 Object* obj;
8475 { TryAllocation t = EnsureCapacity(1, &key);
8476 if (!t->ToObject(&obj)) return t;
8477 }
8277 RegExpKey key(src, flags); 8478 RegExpKey key(src, flags);
8278 Object* obj = EnsureCapacity(1, &key);
8279 if (obj->IsFailure()) return obj;
8280 8479
8281 CompilationCacheTable* cache = 8480 CompilationCacheTable* cache =
8282 reinterpret_cast<CompilationCacheTable*>(obj); 8481 reinterpret_cast<CompilationCacheTable*>(obj);
8283 int entry = cache->FindInsertionEntry(key.Hash()); 8482 int entry = cache->FindInsertionEntry(key.Hash());
8284 // We store the value in the key slot, and compare the search key 8483 // We store the value in the key slot, and compare the search key
8285 // to the stored value with a custon IsMatch function during lookups. 8484 // to the stored value with a custon IsMatch function during lookups.
8286 cache->set(EntryToIndex(entry), value); 8485 cache->set(EntryToIndex(entry), value);
8287 cache->set(EntryToIndex(entry) + 1, value); 8486 cache->set(EntryToIndex(entry) + 1, value);
8288 cache->ElementAdded(); 8487 cache->ElementAdded();
8289 return cache; 8488 return cache;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
8326 8525
8327 Object* MapCache::Lookup(FixedArray* array) { 8526 Object* MapCache::Lookup(FixedArray* array) {
8328 SymbolsKey key(array); 8527 SymbolsKey key(array);
8329 int entry = FindEntry(&key); 8528 int entry = FindEntry(&key);
8330 if (entry == kNotFound) return Heap::undefined_value(); 8529 if (entry == kNotFound) return Heap::undefined_value();
8331 return get(EntryToIndex(entry) + 1); 8530 return get(EntryToIndex(entry) + 1);
8332 } 8531 }
8333 8532
8334 8533
8335 Object* MapCache::Put(FixedArray* array, Map* value) { 8534 Object* MapCache::Put(FixedArray* array, Map* value) {
8535 Object* obj;
8536 { TryAllocation t = EnsureCapacity(1, &key);
8537 if (!t->ToObject(&obj)) return t;
8538 }
8336 SymbolsKey key(array); 8539 SymbolsKey key(array);
8337 Object* obj = EnsureCapacity(1, &key);
8338 if (obj->IsFailure()) return obj;
8339 8540
8340 MapCache* cache = reinterpret_cast<MapCache*>(obj); 8541 MapCache* cache = reinterpret_cast<MapCache*>(obj);
8341 int entry = cache->FindInsertionEntry(key.Hash()); 8542 int entry = cache->FindInsertionEntry(key.Hash());
8342 cache->set(EntryToIndex(entry), array); 8543 cache->set(EntryToIndex(entry), array);
8343 cache->set(EntryToIndex(entry) + 1, value); 8544 cache->set(EntryToIndex(entry) + 1, value);
8344 cache->ElementAdded(); 8545 cache->ElementAdded();
8345 return cache; 8546 return cache;
8346 } 8547 }
8347 8548
8348 8549
8349 template<typename Shape, typename Key> 8550 template<typename Shape, typename Key>
8350 Object* Dictionary<Shape, Key>::Allocate(int at_least_space_for) { 8551 Object* Dictionary<Shape, Key>::Allocate(int at_least_space_for) {
8351 Object* obj = HashTable<Shape, Key>::Allocate(at_least_space_for); 8552 Object* obj = HashTable<Shape, Key>::Allocate(at_least_space_for);
8352 // Initialize the next enumeration index. 8553 // Initialize the next enumeration index.
8353 if (!obj->IsFailure()) { 8554 if (!obj->IsFailure()) {
8354 Dictionary<Shape, Key>::cast(obj)-> 8555 Dictionary<Shape, Key>::cast(obj)->
8355 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); 8556 SetNextEnumerationIndex(PropertyDetails::kInitialIndex);
8356 } 8557 }
8357 return obj; 8558 return obj;
8358 } 8559 }
8359 8560
8360 8561
8361 template<typename Shape, typename Key> 8562 template<typename Shape, typename Key>
8362 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { 8563 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() {
8363 int length = HashTable<Shape, Key>::NumberOfElements(); 8564 int length = HashTable<Shape, Key>::NumberOfElements();
8364 8565
8566 Object* obj;
8567 { TryAllocation t = Heap::AllocateFixedArray(length);
8568 if (!t->ToObject(&obj)) return t;
8569 }
8365 // Allocate and initialize iteration order array. 8570 // Allocate and initialize iteration order array.
8366 Object* obj = Heap::AllocateFixedArray(length);
8367 if (obj->IsFailure()) return obj;
8368 FixedArray* iteration_order = FixedArray::cast(obj); 8571 FixedArray* iteration_order = FixedArray::cast(obj);
8369 for (int i = 0; i < length; i++) { 8572 for (int i = 0; i < length; i++) {
8370 iteration_order->set(i, Smi::FromInt(i)); 8573 iteration_order->set(i, Smi::FromInt(i));
8371 } 8574 }
8372 8575
8576 { TryAllocation t = Heap::AllocateFixedArray(length);
8577 if (!t->ToObject(&obj)) return t;
8578 }
8373 // Allocate array with enumeration order. 8579 // Allocate array with enumeration order.
8374 obj = Heap::AllocateFixedArray(length);
8375 if (obj->IsFailure()) return obj;
8376 FixedArray* enumeration_order = FixedArray::cast(obj); 8580 FixedArray* enumeration_order = FixedArray::cast(obj);
8377 8581
8378 // Fill the enumeration order array with property details. 8582 // Fill the enumeration order array with property details.
8379 int capacity = HashTable<Shape, Key>::Capacity(); 8583 int capacity = HashTable<Shape, Key>::Capacity();
8380 int pos = 0; 8584 int pos = 0;
8381 for (int i = 0; i < capacity; i++) { 8585 for (int i = 0; i < capacity; i++) {
8382 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { 8586 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
8383 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); 8587 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index()));
8384 } 8588 }
8385 } 8589 }
(...skipping 24 matching lines...) Expand all
8410 // Set the next enumeration index. 8614 // Set the next enumeration index.
8411 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); 8615 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
8412 return this; 8616 return this;
8413 } 8617 }
8414 8618
8415 template<typename Shape, typename Key> 8619 template<typename Shape, typename Key>
8416 Object* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { 8620 Object* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) {
8417 // Check whether there are enough enumeration indices to add n elements. 8621 // Check whether there are enough enumeration indices to add n elements.
8418 if (Shape::kIsEnumerable && 8622 if (Shape::kIsEnumerable &&
8419 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { 8623 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) {
8624 Object* result;
8625 { TryAllocation t = GenerateNewEnumerationIndices();
8626 if (!t->ToObject(&result)) return t;
8627 }
8420 // If not, we generate new indices for the properties. 8628 // If not, we generate new indices for the properties.
8421 Object* result = GenerateNewEnumerationIndices();
8422 if (result->IsFailure()) return result;
8423 } 8629 }
8424 return HashTable<Shape, Key>::EnsureCapacity(n, key); 8630 return HashTable<Shape, Key>::EnsureCapacity(n, key);
8425 } 8631 }
8426 8632
8427 8633
8428 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { 8634 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) {
8429 // Do nothing if the interval [from, to) is empty. 8635 // Do nothing if the interval [from, to) is empty.
8430 if (from >= to) return; 8636 if (from >= to) return;
8431 8637
8432 int removed_entries = 0; 8638 int removed_entries = 0;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
8465 template<typename Shape, typename Key> 8671 template<typename Shape, typename Key>
8466 Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { 8672 Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) {
8467 int entry = this->FindEntry(key); 8673 int entry = this->FindEntry(key);
8468 8674
8469 // If the entry is present set the value; 8675 // If the entry is present set the value;
8470 if (entry != Dictionary<Shape, Key>::kNotFound) { 8676 if (entry != Dictionary<Shape, Key>::kNotFound) {
8471 ValueAtPut(entry, value); 8677 ValueAtPut(entry, value);
8472 return this; 8678 return this;
8473 } 8679 }
8474 8680
8681 Object* obj;
8682 { TryAllocation t = EnsureCapacity(1, key);
8683 if (!t->ToObject(&obj)) return t;
8684 }
8475 // Check whether the dictionary should be extended. 8685 // Check whether the dictionary should be extended.
8476 Object* obj = EnsureCapacity(1, key); 8686 Object* k;
8477 if (obj->IsFailure()) return obj; 8687 { TryAllocation t = Shape::AsObject(key);
8688 if (!t->ToObject(&k)) return t;
8689 }
8478 8690
8479 Object* k = Shape::AsObject(key);
8480 if (k->IsFailure()) return k;
8481 PropertyDetails details = PropertyDetails(NONE, NORMAL); 8691 PropertyDetails details = PropertyDetails(NONE, NORMAL);
8482 return Dictionary<Shape, Key>::cast(obj)-> 8692 return Dictionary<Shape, Key>::cast(obj)->
8483 AddEntry(key, value, details, Shape::Hash(key)); 8693 AddEntry(key, value, details, Shape::Hash(key));
8484 } 8694 }
8485 8695
8486 8696
8487 template<typename Shape, typename Key> 8697 template<typename Shape, typename Key>
8488 Object* Dictionary<Shape, Key>::Add(Key key, 8698 Object* Dictionary<Shape, Key>::Add(Key key,
8489 Object* value, 8699 Object* value,
8490 PropertyDetails details) { 8700 PropertyDetails details) {
8491 // Valdate key is absent. 8701 // Valdate key is absent.
8492 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); 8702 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound));
8703 Object* obj;
8704 { TryAllocation t = EnsureCapacity(1, key);
8705 if (!t->ToObject(&obj)) return t;
8706 }
8493 // Check whether the dictionary should be extended. 8707 // Check whether the dictionary should be extended.
8494 Object* obj = EnsureCapacity(1, key);
8495 if (obj->IsFailure()) return obj;
8496 return Dictionary<Shape, Key>::cast(obj)-> 8708 return Dictionary<Shape, Key>::cast(obj)->
8497 AddEntry(key, value, details, Shape::Hash(key)); 8709 AddEntry(key, value, details, Shape::Hash(key));
8498 } 8710 }
8499 8711
8500 8712
8501 // Add a key, value pair to the dictionary. 8713 // Add a key, value pair to the dictionary.
8502 template<typename Shape, typename Key> 8714 template<typename Shape, typename Key>
8503 Object* Dictionary<Shape, Key>::AddEntry(Key key, 8715 Object* Dictionary<Shape, Key>::AddEntry(Key key,
8504 Object* value, 8716 Object* value,
8505 PropertyDetails details, 8717 PropertyDetails details,
8506 uint32_t hash) { 8718 uint32_t hash) {
8719 Object* k;
8720 { TryAllocation t = Shape::AsObject(key);
8721 if (!t->ToObject(&k)) return t;
8722 }
8507 // Compute the key object. 8723 // Compute the key object.
8508 Object* k = Shape::AsObject(key);
8509 if (k->IsFailure()) return k;
8510 8724
8511 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); 8725 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash);
8512 // Insert element at empty or deleted entry 8726 // Insert element at empty or deleted entry
8513 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) { 8727 if (!details.IsDeleted() && details.index() == 0 && Shape::kIsEnumerable) {
8514 // Assign an enumeration index to the property and update 8728 // Assign an enumeration index to the property and update
8515 // SetNextEnumerationIndex. 8729 // SetNextEnumerationIndex.
8516 int index = NextEnumerationIndex(); 8730 int index = NextEnumerationIndex();
8517 details = PropertyDetails(details.attributes(), details.type(), index); 8731 details = PropertyDetails(details.attributes(), details.type(), index);
8518 SetNextEnumerationIndex(index + 1); 8732 SetNextEnumerationIndex(index + 1);
8519 } 8733 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
8679 JSObject* obj, int unused_property_fields) { 8893 JSObject* obj, int unused_property_fields) {
8680 // Make sure we preserve dictionary representation if there are too many 8894 // Make sure we preserve dictionary representation if there are too many
8681 // descriptors. 8895 // descriptors.
8682 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; 8896 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj;
8683 8897
8684 // Figure out if it is necessary to generate new enumeration indices. 8898 // Figure out if it is necessary to generate new enumeration indices.
8685 int max_enumeration_index = 8899 int max_enumeration_index =
8686 NextEnumerationIndex() + 8900 NextEnumerationIndex() +
8687 (DescriptorArray::kMaxNumberOfDescriptors - 8901 (DescriptorArray::kMaxNumberOfDescriptors -
8688 NumberOfElements()); 8902 NumberOfElements());
8903 Object* result;
8904 { TryAllocation t = GenerateNewEnumerationIndices();
8905 if (!t->ToObject(&result)) return t;
8906 }
8689 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { 8907 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) {
8690 Object* result = GenerateNewEnumerationIndices();
8691 if (result->IsFailure()) return result;
8692 } 8908 }
8693 8909
8694 int instance_descriptor_length = 0; 8910 int instance_descriptor_length = 0;
8695 int number_of_fields = 0; 8911 int number_of_fields = 0;
8696 8912
8697 // Compute the length of the instance descriptor. 8913 // Compute the length of the instance descriptor.
8698 int capacity = Capacity(); 8914 int capacity = Capacity();
8699 for (int i = 0; i < capacity; i++) { 8915 for (int i = 0; i < capacity; i++) {
8700 Object* k = KeyAt(i); 8916 Object* k = KeyAt(i);
8701 if (IsKey(k)) { 8917 if (IsKey(k)) {
8702 Object* value = ValueAt(i); 8918 Object* value = ValueAt(i);
8703 PropertyType type = DetailsAt(i).type(); 8919 PropertyType type = DetailsAt(i).type();
8704 ASSERT(type != FIELD); 8920 ASSERT(type != FIELD);
8705 instance_descriptor_length++; 8921 instance_descriptor_length++;
8706 if (type == NORMAL && 8922 if (type == NORMAL &&
8707 (!value->IsJSFunction() || Heap::InNewSpace(value))) { 8923 (!value->IsJSFunction() || Heap::InNewSpace(value))) {
8708 number_of_fields += 1; 8924 number_of_fields += 1;
8709 } 8925 }
8710 } 8926 }
8711 } 8927 }
8712 8928
8713 // Allocate the instance descriptor. 8929 // Allocate the instance descriptor.
8714 Object* descriptors_unchecked = 8930 Object* descriptors_unchecked;
8715 DescriptorArray::Allocate(instance_descriptor_length); 8931 { TryAllocation t =
8716 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; 8932 DescriptorArray::Allocate(instance_descriptor_length);
8933 if (!t->ToObject(&descriptors_unchecked)) return t;
8934 }
8717 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); 8935 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked);
8718 8936
8719 int inobject_props = obj->map()->inobject_properties(); 8937 int inobject_props = obj->map()->inobject_properties();
8720 int number_of_allocated_fields = 8938 int number_of_allocated_fields =
8721 number_of_fields + unused_property_fields - inobject_props; 8939 number_of_fields + unused_property_fields - inobject_props;
8722 8940
8941 Object* fields;
8942 { TryAllocation t = Heap::AllocateFixedArray(number_of_allocated_fields);
8943 if (!t->ToObject(&fields)) return t;
8944 }
8723 // Allocate the fixed array for the fields. 8945 // Allocate the fixed array for the fields.
8724 Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields);
8725 if (fields->IsFailure()) return fields;
8726 8946
8727 // Fill in the instance descriptor and the fields. 8947 // Fill in the instance descriptor and the fields.
8728 int next_descriptor = 0; 8948 int next_descriptor = 0;
8729 int current_offset = 0; 8949 int current_offset = 0;
8730 for (int i = 0; i < capacity; i++) { 8950 for (int i = 0; i < capacity; i++) {
8731 Object* k = KeyAt(i); 8951 Object* k = KeyAt(i);
8732 if (IsKey(k)) { 8952 if (IsKey(k)) {
8733 Object* value = ValueAt(i); 8953 Object* value = ValueAt(i);
8954 Object* key;
8955 { TryAllocation t = Heap::LookupSymbol(String::cast(k));
8956 if (!t->ToObject(&key)) return t;
8957 }
8734 // Ensure the key is a symbol before writing into the instance descriptor. 8958 // Ensure the key is a symbol before writing into the instance descriptor.
8735 Object* key = Heap::LookupSymbol(String::cast(k));
8736 if (key->IsFailure()) return key;
8737 PropertyDetails details = DetailsAt(i); 8959 PropertyDetails details = DetailsAt(i);
8738 PropertyType type = details.type(); 8960 PropertyType type = details.type();
8739 8961
8740 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { 8962 if (value->IsJSFunction() && !Heap::InNewSpace(value)) {
8741 ConstantFunctionDescriptor d(String::cast(key), 8963 ConstantFunctionDescriptor d(String::cast(key),
8742 JSFunction::cast(value), 8964 JSFunction::cast(value),
8743 details.attributes(), 8965 details.attributes(),
8744 details.index()); 8966 details.index());
8745 descriptors->Set(next_descriptor++, &d); 8967 descriptors->Set(next_descriptor++, &d);
8746 } else if (type == NORMAL) { 8968 } else if (type == NORMAL) {
(...skipping 17 matching lines...) Expand all
8764 details.index()); 8986 details.index());
8765 descriptors->Set(next_descriptor++, &d); 8987 descriptors->Set(next_descriptor++, &d);
8766 } else { 8988 } else {
8767 UNREACHABLE(); 8989 UNREACHABLE();
8768 } 8990 }
8769 } 8991 }
8770 } 8992 }
8771 ASSERT(current_offset == number_of_fields); 8993 ASSERT(current_offset == number_of_fields);
8772 8994
8773 descriptors->Sort(); 8995 descriptors->Sort();
8996 Object* new_map;
8997 { TryAllocation t = obj->map()->CopyDropDescriptors();
8998 if (!t->ToObject(&new_map)) return t;
8999 }
8774 // Allocate new map. 9000 // Allocate new map.
8775 Object* new_map = obj->map()->CopyDropDescriptors();
8776 if (new_map->IsFailure()) return new_map;
8777 9001
8778 // Transform the object. 9002 // Transform the object.
8779 obj->set_map(Map::cast(new_map)); 9003 obj->set_map(Map::cast(new_map));
8780 obj->map()->set_instance_descriptors(descriptors); 9004 obj->map()->set_instance_descriptors(descriptors);
8781 obj->map()->set_unused_property_fields(unused_property_fields); 9005 obj->map()->set_unused_property_fields(unused_property_fields);
8782 9006
8783 obj->set_properties(FixedArray::cast(fields)); 9007 obj->set_properties(FixedArray::cast(fields));
8784 ASSERT(obj->IsJSObject()); 9008 ASSERT(obj->IsJSObject());
8785 9009
8786 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); 9010 descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
9032 if (break_point_objects()->IsUndefined()) return 0; 9256 if (break_point_objects()->IsUndefined()) return 0;
9033 // Single beak point. 9257 // Single beak point.
9034 if (!break_point_objects()->IsFixedArray()) return 1; 9258 if (!break_point_objects()->IsFixedArray()) return 1;
9035 // Multiple break points. 9259 // Multiple break points.
9036 return FixedArray::cast(break_point_objects())->length(); 9260 return FixedArray::cast(break_point_objects())->length();
9037 } 9261 }
9038 #endif 9262 #endif
9039 9263
9040 9264
9041 } } // namespace v8::internal 9265 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698