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

Side by Side Diff: src/runtime.cc

Issue 10626004: Cleaning up usage of lookup results. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 6 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 return heap->undefined_value(); 1108 return heap->undefined_value();
1109 } 1109 }
1110 1110
1111 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { 1111 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) {
1112 return heap->false_value(); 1112 return heap->false_value();
1113 } 1113 }
1114 1114
1115 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); 1115 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum()));
1116 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); 1116 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete()));
1117 1117
1118 bool is_js_accessor = (result.type() == CALLBACKS) && 1118 bool is_js_accessor = result.IsCallbacks() &&
1119 (result.GetCallbackObject()->IsAccessorPair()); 1119 (result.GetCallbackObject()->IsAccessorPair());
1120 1120
1121 if (is_js_accessor) { 1121 if (is_js_accessor) {
1122 // __defineGetter__/__defineSetter__ callback. 1122 // __defineGetter__/__defineSetter__ callback.
1123 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); 1123 elms->set(IS_ACCESSOR_INDEX, heap->true_value());
1124 1124
1125 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); 1125 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject());
1126 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); 1126 Object* getter = accessors->GetComponent(ACCESSOR_GETTER);
1127 if (!getter->IsMap() && CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { 1127 if (!getter->IsMap() && CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
1128 elms->set(GETTER_INDEX, getter); 1128 elms->set(GETTER_INDEX, getter);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 JSObject::cast(obj)->LocalLookup(*name, &lookup); 1320 JSObject::cast(obj)->LocalLookup(*name, &lookup);
1321 obj = obj->GetPrototype(); 1321 obj = obj->GetPrototype();
1322 } while (!lookup.IsFound() && obj->IsJSObject() && 1322 } while (!lookup.IsFound() && obj->IsJSObject() &&
1323 JSObject::cast(obj)->map()->is_hidden_prototype()); 1323 JSObject::cast(obj)->map()->is_hidden_prototype());
1324 } else { 1324 } else {
1325 global->Lookup(*name, &lookup); 1325 global->Lookup(*name, &lookup);
1326 } 1326 }
1327 if (lookup.IsProperty()) { 1327 if (lookup.IsProperty()) {
1328 // We found an existing property. Unless it was an interceptor 1328 // We found an existing property. Unless it was an interceptor
1329 // that claims the property is absent, skip this declaration. 1329 // that claims the property is absent, skip this declaration.
1330 if (lookup.type() != INTERCEPTOR) continue; 1330 if (!lookup.IsInterceptor()) continue;
1331 PropertyAttributes attributes = global->GetPropertyAttribute(*name); 1331 PropertyAttributes attributes = global->GetPropertyAttribute(*name);
1332 if (attributes != ABSENT) continue; 1332 if (attributes != ABSENT) continue;
1333 // Fall-through and introduce the absent property by using 1333 // Fall-through and introduce the absent property by using
1334 // SetProperty. 1334 // SetProperty.
1335 } 1335 }
1336 } else if (is_function) { 1336 } else if (is_function) {
1337 // Copy the function and update its context. Use it as value. 1337 // Copy the function and update its context. Use it as value.
1338 Handle<SharedFunctionInfo> shared = 1338 Handle<SharedFunctionInfo> shared =
1339 Handle<SharedFunctionInfo>::cast(value); 1339 Handle<SharedFunctionInfo>::cast(value);
1340 Handle<JSFunction> function = 1340 Handle<JSFunction> function =
(...skipping 17 matching lines...) Expand all
1358 attr |= READ_ONLY; 1358 attr |= READ_ONLY;
1359 } 1359 }
1360 1360
1361 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); 1361 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags);
1362 1362
1363 if (!lookup.IsProperty() || is_function || is_module) { 1363 if (!lookup.IsProperty() || is_function || is_module) {
1364 // If the local property exists, check that we can reconfigure it 1364 // If the local property exists, check that we can reconfigure it
1365 // as required for function declarations. 1365 // as required for function declarations.
1366 if (lookup.IsProperty() && lookup.IsDontDelete()) { 1366 if (lookup.IsProperty() && lookup.IsDontDelete()) {
1367 if (lookup.IsReadOnly() || lookup.IsDontEnum() || 1367 if (lookup.IsReadOnly() || lookup.IsDontEnum() ||
1368 lookup.type() == CALLBACKS) { 1368 lookup.IsCallbacks()) {
1369 return ThrowRedeclarationError( 1369 return ThrowRedeclarationError(
1370 isolate, is_function ? "function" : "module", name); 1370 isolate, is_function ? "function" : "module", name);
1371 } 1371 }
1372 // If the existing property is not configurable, keep its attributes. 1372 // If the existing property is not configurable, keep its attributes.
1373 attr = lookup.GetAttributes(); 1373 attr = lookup.GetAttributes();
1374 } 1374 }
1375 // Define or redefine own property. 1375 // Define or redefine own property.
1376 RETURN_IF_EMPTY_HANDLE(isolate, 1376 RETURN_IF_EMPTY_HANDLE(isolate,
1377 JSObject::SetLocalPropertyIgnoreAttributes( 1377 JSObject::SetLocalPropertyIgnoreAttributes(
1378 global, name, value, static_cast<PropertyAttributes>(attr))); 1378 global, name, value, static_cast<PropertyAttributes>(attr)));
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1467 // Declaring a const context slot is a conflicting declaration if 1467 // Declaring a const context slot is a conflicting declaration if
1468 // there is a callback with that name in a prototype. It is 1468 // there is a callback with that name in a prototype. It is
1469 // allowed to introduce const variables in 1469 // allowed to introduce const variables in
1470 // JSContextExtensionObjects. They are treated specially in 1470 // JSContextExtensionObjects. They are treated specially in
1471 // SetProperty and no setters are invoked for those since they are 1471 // SetProperty and no setters are invoked for those since they are
1472 // not real JSObjects. 1472 // not real JSObjects.
1473 if (initial_value->IsTheHole() && 1473 if (initial_value->IsTheHole() &&
1474 !object->IsJSContextExtensionObject()) { 1474 !object->IsJSContextExtensionObject()) {
1475 LookupResult lookup(isolate); 1475 LookupResult lookup(isolate);
1476 object->Lookup(*name, &lookup); 1476 object->Lookup(*name, &lookup);
1477 if (lookup.IsFound() && (lookup.type() == CALLBACKS)) { 1477 if (lookup.IsCallbacks()) {
1478 return ThrowRedeclarationError(isolate, "const", name); 1478 return ThrowRedeclarationError(isolate, "const", name);
1479 } 1479 }
1480 } 1480 }
1481 if (object->IsJSGlobalObject()) { 1481 if (object->IsJSGlobalObject()) {
1482 // Define own property on the global object. 1482 // Define own property on the global object.
1483 RETURN_IF_EMPTY_HANDLE(isolate, 1483 RETURN_IF_EMPTY_HANDLE(isolate,
1484 JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode)); 1484 JSObject::SetLocalPropertyIgnoreAttributes(object, name, value, mode));
1485 } else { 1485 } else {
1486 RETURN_IF_EMPTY_HANDLE(isolate, 1486 RETURN_IF_EMPTY_HANDLE(isolate,
1487 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); 1487 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1520 // locally if there is an explicit initialization value that we have 1520 // locally if there is an explicit initialization value that we have
1521 // to assign to the property. 1521 // to assign to the property.
1522 // Note that objects can have hidden prototypes, so we need to traverse 1522 // Note that objects can have hidden prototypes, so we need to traverse
1523 // the whole chain of hidden prototypes to do a 'local' lookup. 1523 // the whole chain of hidden prototypes to do a 'local' lookup.
1524 Object* object = global; 1524 Object* object = global;
1525 LookupResult lookup(isolate); 1525 LookupResult lookup(isolate);
1526 while (object->IsJSObject() && 1526 while (object->IsJSObject() &&
1527 JSObject::cast(object)->map()->is_hidden_prototype()) { 1527 JSObject::cast(object)->map()->is_hidden_prototype()) {
1528 JSObject* raw_holder = JSObject::cast(object); 1528 JSObject* raw_holder = JSObject::cast(object);
1529 raw_holder->LocalLookup(*name, &lookup); 1529 raw_holder->LocalLookup(*name, &lookup);
1530 if (lookup.IsFound() && lookup.type() == INTERCEPTOR) { 1530 if (lookup.IsInterceptor()) {
1531 HandleScope handle_scope(isolate); 1531 HandleScope handle_scope(isolate);
1532 Handle<JSObject> holder(raw_holder); 1532 Handle<JSObject> holder(raw_holder);
1533 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name); 1533 PropertyAttributes intercepted = holder->GetPropertyAttribute(*name);
1534 // Update the raw pointer in case it's changed due to GC. 1534 // Update the raw pointer in case it's changed due to GC.
1535 raw_holder = *holder; 1535 raw_holder = *holder;
1536 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { 1536 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
1537 // Found an interceptor that's not read only. 1537 // Found an interceptor that's not read only.
1538 if (assign) { 1538 if (assign) {
1539 return raw_holder->SetProperty( 1539 return raw_holder->SetProperty(
1540 &lookup, *name, args[2], attributes, strict_mode_flag); 1540 &lookup, *name, args[2], attributes, strict_mode_flag);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 isolate, 1598 isolate,
1599 JSReceiver::SetProperty(global, name, value, attributes, 1599 JSReceiver::SetProperty(global, name, value, attributes,
1600 kNonStrictMode)); 1600 kNonStrictMode));
1601 return *value; 1601 return *value;
1602 } 1602 }
1603 1603
1604 // Set the value, but only if we're assigning the initial value to a 1604 // Set the value, but only if we're assigning the initial value to a
1605 // constant. For now, we determine this by checking if the 1605 // constant. For now, we determine this by checking if the
1606 // current value is the hole. 1606 // current value is the hole.
1607 // Strict mode handling not needed (const is disallowed in strict mode). 1607 // Strict mode handling not needed (const is disallowed in strict mode).
1608 PropertyType type = lookup.type(); 1608 if (lookup.IsField()) {
1609 if (type == FIELD) {
1610 FixedArray* properties = global->properties(); 1609 FixedArray* properties = global->properties();
1611 int index = lookup.GetFieldIndex(); 1610 int index = lookup.GetFieldIndex();
1612 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) { 1611 if (properties->get(index)->IsTheHole() || !lookup.IsReadOnly()) {
1613 properties->set(index, *value); 1612 properties->set(index, *value);
1614 } 1613 }
1615 } else if (type == NORMAL) { 1614 } else if (lookup.IsNormal()) {
1616 if (global->GetNormalizedProperty(&lookup)->IsTheHole() || 1615 if (global->GetNormalizedProperty(&lookup)->IsTheHole() ||
1617 !lookup.IsReadOnly()) { 1616 !lookup.IsReadOnly()) {
1618 global->SetNormalizedProperty(&lookup, *value); 1617 global->SetNormalizedProperty(&lookup, *value);
1619 } 1618 }
1620 } else { 1619 } else {
1621 // Ignore re-initialization of constants that have already been 1620 // Ignore re-initialization of constants that have already been
1622 // assigned a function value. 1621 // assigned a function value.
1623 ASSERT(lookup.IsReadOnly() && type == CONSTANT_FUNCTION); 1622 ASSERT(lookup.IsReadOnly() && lookup.IsConstantFunction());
1624 } 1623 }
1625 1624
1626 // Use the set value as the result of the operation. 1625 // Use the set value as the result of the operation.
1627 return *value; 1626 return *value;
1628 } 1627 }
1629 1628
1630 1629
1631 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) { 1630 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstContextSlot) {
1632 HandleScope scope(isolate); 1631 HandleScope scope(isolate);
1633 ASSERT(args.length() == 3); 1632 ASSERT(args.length() == 3);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 1688
1690 if (*object == context->extension()) { 1689 if (*object == context->extension()) {
1691 // This is the property that was introduced by the const declaration. 1690 // This is the property that was introduced by the const declaration.
1692 // Set it if it hasn't been set before. NOTE: We cannot use 1691 // Set it if it hasn't been set before. NOTE: We cannot use
1693 // GetProperty() to get the current value as it 'unholes' the value. 1692 // GetProperty() to get the current value as it 'unholes' the value.
1694 LookupResult lookup(isolate); 1693 LookupResult lookup(isolate);
1695 object->LocalLookupRealNamedProperty(*name, &lookup); 1694 object->LocalLookupRealNamedProperty(*name, &lookup);
1696 ASSERT(lookup.IsFound()); // the property was declared 1695 ASSERT(lookup.IsFound()); // the property was declared
1697 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only 1696 ASSERT(lookup.IsReadOnly()); // and it was declared as read-only
1698 1697
1699 PropertyType type = lookup.type(); 1698 if (lookup.IsField()) {
1700 if (type == FIELD) {
1701 FixedArray* properties = object->properties(); 1699 FixedArray* properties = object->properties();
1702 int index = lookup.GetFieldIndex(); 1700 int index = lookup.GetFieldIndex();
1703 if (properties->get(index)->IsTheHole()) { 1701 if (properties->get(index)->IsTheHole()) {
1704 properties->set(index, *value); 1702 properties->set(index, *value);
1705 } 1703 }
1706 } else if (type == NORMAL) { 1704 } else if (lookup.IsNormal()) {
1707 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) { 1705 if (object->GetNormalizedProperty(&lookup)->IsTheHole()) {
1708 object->SetNormalizedProperty(&lookup, *value); 1706 object->SetNormalizedProperty(&lookup, *value);
1709 } 1707 }
1710 } else { 1708 } else {
1711 // We should not reach here. Any real, named property should be 1709 // We should not reach here. Any real, named property should be
1712 // either a field or a dictionary slot. 1710 // either a field or a dictionary slot.
1713 UNREACHABLE(); 1711 UNREACHABLE();
1714 } 1712 }
1715 } else { 1713 } else {
1716 // The property was found on some other object. Set it if it is not a 1714 // The property was found on some other object. Set it if it is not a
(...skipping 2648 matching lines...) Expand 10 before | Expand all | Expand 10 after
4365 if (offset != -1) { 4363 if (offset != -1) {
4366 Object* value = receiver->FastPropertyAt(offset); 4364 Object* value = receiver->FastPropertyAt(offset);
4367 return value->IsTheHole() 4365 return value->IsTheHole()
4368 ? isolate->heap()->undefined_value() 4366 ? isolate->heap()->undefined_value()
4369 : value; 4367 : value;
4370 } 4368 }
4371 // Lookup cache miss. Perform lookup and update the cache if 4369 // Lookup cache miss. Perform lookup and update the cache if
4372 // appropriate. 4370 // appropriate.
4373 LookupResult result(isolate); 4371 LookupResult result(isolate);
4374 receiver->LocalLookup(key, &result); 4372 receiver->LocalLookup(key, &result);
4375 if (result.IsFound() && result.type() == FIELD) { 4373 if (result.IsField()) {
4376 int offset = result.GetFieldIndex(); 4374 int offset = result.GetFieldIndex();
4377 keyed_lookup_cache->Update(receiver_map, key, offset); 4375 keyed_lookup_cache->Update(receiver_map, key, offset);
4378 return receiver->FastPropertyAt(offset); 4376 return receiver->FastPropertyAt(offset);
4379 } 4377 }
4380 } else { 4378 } else {
4381 // Attempt dictionary lookup. 4379 // Attempt dictionary lookup.
4382 StringDictionary* dictionary = receiver->property_dictionary(); 4380 StringDictionary* dictionary = receiver->property_dictionary();
4383 int entry = dictionary->FindEntry(key); 4381 int entry = dictionary->FindEntry(key);
4384 if ((entry != StringDictionary::kNotFound) && 4382 if ((entry != StringDictionary::kNotFound) &&
4385 (dictionary->DetailsAt(entry).type() == NORMAL)) { 4383 (dictionary->DetailsAt(entry).type() == NORMAL)) {
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
4477 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 4475 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
4478 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); 4476 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
4479 CONVERT_SMI_ARG_CHECKED(unchecked, 3); 4477 CONVERT_SMI_ARG_CHECKED(unchecked, 3);
4480 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4478 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4481 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4479 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4482 4480
4483 LookupResult result(isolate); 4481 LookupResult result(isolate);
4484 js_object->LocalLookupRealNamedProperty(*name, &result); 4482 js_object->LocalLookupRealNamedProperty(*name, &result);
4485 4483
4486 // Special case for callback properties. 4484 // Special case for callback properties.
4487 if (result.IsFound() && result.type() == CALLBACKS) { 4485 if (result.IsCallbacks()) {
4488 Object* callback = result.GetCallbackObject(); 4486 Object* callback = result.GetCallbackObject();
4489 // To be compatible with Safari we do not change the value on API objects 4487 // To be compatible with Safari we do not change the value on API objects
4490 // in Object.defineProperty(). Firefox disagrees here, and actually changes 4488 // in Object.defineProperty(). Firefox disagrees here, and actually changes
4491 // the value. 4489 // the value.
4492 if (callback->IsAccessorInfo()) { 4490 if (callback->IsAccessorInfo()) {
4493 return isolate->heap()->undefined_value(); 4491 return isolate->heap()->undefined_value();
4494 } 4492 }
4495 // Avoid redefining foreign callback as data property, just use the stored 4493 // Avoid redefining foreign callback as data property, just use the stored
4496 // setter to update the value instead. 4494 // setter to update the value instead.
4497 // TODO(mstarzinger): So far this only works if property attributes don't 4495 // TODO(mstarzinger): So far this only works if property attributes don't
4498 // change, this should be fixed once we cleanup the underlying code. 4496 // change, this should be fixed once we cleanup the underlying code.
4499 if (callback->IsForeign() && result.GetAttributes() == attr) { 4497 if (callback->IsForeign() && result.GetAttributes() == attr) {
4500 return js_object->SetPropertyWithCallback(callback, 4498 return js_object->SetPropertyWithCallback(callback,
4501 *name, 4499 *name,
4502 *obj_value, 4500 *obj_value,
4503 result.holder(), 4501 result.holder(),
4504 kStrictMode); 4502 kStrictMode);
4505 } 4503 }
4506 } 4504 }
4507 4505
4508 // Take special care when attributes are different and there is already 4506 // Take special care when attributes are different and there is already
4509 // a property. For simplicity we normalize the property which enables us 4507 // a property. For simplicity we normalize the property which enables us
4510 // to not worry about changing the instance_descriptor and creating a new 4508 // to not worry about changing the instance_descriptor and creating a new
4511 // map. The current version of SetObjectProperty does not handle attributes 4509 // map. The current version of SetObjectProperty does not handle attributes
4512 // correctly in the case where a property is a field and is reset with 4510 // correctly in the case where a property is a field and is reset with
4513 // new attributes. 4511 // new attributes.
4514 if (result.IsProperty() && 4512 if (result.IsProperty() &&
4515 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { 4513 (attr != result.GetAttributes() || result.IsCallbacks())) {
4516 // New attributes - normalize to avoid writing to instance descriptor 4514 // New attributes - normalize to avoid writing to instance descriptor
4517 if (js_object->IsJSGlobalProxy()) { 4515 if (js_object->IsJSGlobalProxy()) {
4518 // Since the result is a property, the prototype will exist so 4516 // Since the result is a property, the prototype will exist so
4519 // we don't have to check for null. 4517 // we don't have to check for null.
4520 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); 4518 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
4521 } 4519 }
4522 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 4520 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
4523 // Use IgnoreAttributes version since a readonly property may be 4521 // Use IgnoreAttributes version since a readonly property may be
4524 // overridden and SetProperty does not allow this. 4522 // overridden and SetProperty does not allow this.
4525 return js_object->SetLocalPropertyIgnoreAttributes(*name, 4523 return js_object->SetLocalPropertyIgnoreAttributes(*name,
(...skipping 5831 matching lines...) Expand 10 before | Expand all | Expand 10 after
10357 10355
10358 // Try local lookup on each of the objects. 10356 // Try local lookup on each of the objects.
10359 Handle<JSObject> jsproto = obj; 10357 Handle<JSObject> jsproto = obj;
10360 for (int i = 0; i < length; i++) { 10358 for (int i = 0; i < length; i++) {
10361 LookupResult result(isolate); 10359 LookupResult result(isolate);
10362 jsproto->LocalLookup(*name, &result); 10360 jsproto->LocalLookup(*name, &result);
10363 if (result.IsProperty()) { 10361 if (result.IsProperty()) {
10364 // LookupResult is not GC safe as it holds raw object pointers. 10362 // LookupResult is not GC safe as it holds raw object pointers.
10365 // GC can happen later in this code so put the required fields into 10363 // GC can happen later in this code so put the required fields into
10366 // local variables using handles when required for later use. 10364 // local variables using handles when required for later use.
10367 PropertyType result_type = result.type();
10368 Handle<Object> result_callback_obj; 10365 Handle<Object> result_callback_obj;
10369 if (result_type == CALLBACKS) { 10366 if (result.IsCallbacks()) {
10370 result_callback_obj = Handle<Object>(result.GetCallbackObject(), 10367 result_callback_obj = Handle<Object>(result.GetCallbackObject(),
10371 isolate); 10368 isolate);
10372 } 10369 }
10373 Smi* property_details = result.GetPropertyDetails().AsSmi(); 10370 Smi* property_details = result.GetPropertyDetails().AsSmi();
10374 // DebugLookupResultValue can cause GC so details from LookupResult needs 10371 // DebugLookupResultValue can cause GC so details from LookupResult needs
10375 // to be copied to handles before this. 10372 // to be copied to handles before this.
10376 bool caught_exception = false; 10373 bool caught_exception = false;
10377 Object* raw_value; 10374 Object* raw_value;
10378 { MaybeObject* maybe_raw_value = 10375 { MaybeObject* maybe_raw_value =
10379 DebugLookupResultValue(isolate->heap(), *obj, *name, 10376 DebugLookupResultValue(isolate->heap(), *obj, *name,
10380 &result, &caught_exception); 10377 &result, &caught_exception);
10381 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; 10378 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value;
10382 } 10379 }
10383 Handle<Object> value(raw_value, isolate); 10380 Handle<Object> value(raw_value, isolate);
10384 10381
10385 // If the callback object is a fixed array then it contains JavaScript 10382 // If the callback object is a fixed array then it contains JavaScript
10386 // getter and/or setter. 10383 // getter and/or setter.
10387 bool hasJavaScriptAccessors = result_type == CALLBACKS && 10384 bool hasJavaScriptAccessors = result.IsCallbacks() &&
10388 result_callback_obj->IsAccessorPair(); 10385 result_callback_obj->IsAccessorPair();
10389 Handle<FixedArray> details = 10386 Handle<FixedArray> details =
10390 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); 10387 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
10391 details->set(0, *value); 10388 details->set(0, *value);
10392 details->set(1, property_details); 10389 details->set(1, property_details);
10393 if (hasJavaScriptAccessors) { 10390 if (hasJavaScriptAccessors) {
10394 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); 10391 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
10395 details->set(2, isolate->heap()->ToBoolean(caught_exception)); 10392 details->set(2, isolate->heap()->ToBoolean(caught_exception));
10396 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); 10393 details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
10397 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); 10394 details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
(...skipping 3254 matching lines...) Expand 10 before | Expand all | Expand 10 after
13652 // Handle last resort GC and make sure to allow future allocations 13649 // Handle last resort GC and make sure to allow future allocations
13653 // to grow the heap without causing GCs (if possible). 13650 // to grow the heap without causing GCs (if possible).
13654 isolate->counters()->gc_last_resort_from_js()->Increment(); 13651 isolate->counters()->gc_last_resort_from_js()->Increment();
13655 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13652 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13656 "Runtime::PerformGC"); 13653 "Runtime::PerformGC");
13657 } 13654 }
13658 } 13655 }
13659 13656
13660 13657
13661 } } // namespace v8::internal 13658 } } // namespace v8::internal
OLDNEW
« src/property.h ('K') | « src/property.h ('k') | src/x64/lithium-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698