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

Side by Side Diff: src/runtime.cc

Issue 9716035: Make setting of accessors even more atomic. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporated review comments. Created 8 years, 9 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.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 int entry = dictionary->FindEntry(index); 1058 int entry = dictionary->FindEntry(index);
1059 ASSERT(entry != SeededNumberDictionary::kNotFound); 1059 ASSERT(entry != SeededNumberDictionary::kNotFound);
1060 PropertyDetails details = dictionary->DetailsAt(entry); 1060 PropertyDetails details = dictionary->DetailsAt(entry);
1061 switch (details.type()) { 1061 switch (details.type()) {
1062 case CALLBACKS: { 1062 case CALLBACKS: {
1063 // This is an accessor property with getter and/or setter. 1063 // This is an accessor property with getter and/or setter.
1064 AccessorPair* accessors = 1064 AccessorPair* accessors =
1065 AccessorPair::cast(dictionary->ValueAt(entry)); 1065 AccessorPair::cast(dictionary->ValueAt(entry));
1066 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); 1066 elms->set(IS_ACCESSOR_INDEX, heap->true_value());
1067 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { 1067 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) {
1068 elms->set(GETTER_INDEX, accessors->SafeGet(ACCESSOR_GETTER)); 1068 elms->set(GETTER_INDEX, accessors->GetComponent(ACCESSOR_GETTER));
1069 } 1069 }
1070 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { 1070 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) {
1071 elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER)); 1071 elms->set(SETTER_INDEX, accessors->GetComponent(ACCESSOR_SETTER));
1072 } 1072 }
1073 break; 1073 break;
1074 } 1074 }
1075 case NORMAL: { 1075 case NORMAL: {
1076 // This is a data property. 1076 // This is a data property.
1077 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); 1077 elms->set(IS_ACCESSOR_INDEX, heap->false_value());
1078 Handle<Object> value = Object::GetElement(obj, index); 1078 Handle<Object> value = Object::GetElement(obj, index);
1079 ASSERT(!value.is_null()); 1079 ASSERT(!value.is_null());
1080 elms->set(VALUE_INDEX, *value); 1080 elms->set(VALUE_INDEX, *value);
1081 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); 1081 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly()));
(...skipping 26 matching lines...) Expand all
1108 1108
1109 bool is_js_accessor = (result.type() == CALLBACKS) && 1109 bool is_js_accessor = (result.type() == CALLBACKS) &&
1110 (result.GetCallbackObject()->IsAccessorPair()); 1110 (result.GetCallbackObject()->IsAccessorPair());
1111 1111
1112 if (is_js_accessor) { 1112 if (is_js_accessor) {
1113 // __defineGetter__/__defineSetter__ callback. 1113 // __defineGetter__/__defineSetter__ callback.
1114 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); 1114 elms->set(IS_ACCESSOR_INDEX, heap->true_value());
1115 1115
1116 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); 1116 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject());
1117 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { 1117 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) {
1118 elms->set(GETTER_INDEX, accessors->SafeGet(ACCESSOR_GETTER)); 1118 elms->set(GETTER_INDEX, accessors->GetComponent(ACCESSOR_GETTER));
1119 } 1119 }
1120 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { 1120 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) {
1121 elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER)); 1121 elms->set(SETTER_INDEX, accessors->GetComponent(ACCESSOR_SETTER));
1122 } 1122 }
1123 } else { 1123 } else {
1124 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); 1124 elms->set(IS_ACCESSOR_INDEX, heap->false_value());
1125 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); 1125 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly()));
1126 1126
1127 PropertyAttributes attrs; 1127 PropertyAttributes attrs;
1128 Object* value; 1128 Object* value;
1129 // GetProperty will check access and report any violations. 1129 // GetProperty will check access and report any violations.
1130 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); 1130 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
1131 if (!maybe_value->ToObject(&value)) return maybe_value; 1131 if (!maybe_value->ToObject(&value)) return maybe_value;
(...skipping 3211 matching lines...) Expand 10 before | Expand all | Expand 10 after
4343 RUNTIME_ASSERT(!obj->IsNull()); 4343 RUNTIME_ASSERT(!obj->IsNull());
4344 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 4344 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
4345 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); 4345 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4346 RUNTIME_ASSERT(IsValidAccessor(getter)); 4346 RUNTIME_ASSERT(IsValidAccessor(getter));
4347 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); 4347 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4348 RUNTIME_ASSERT(IsValidAccessor(setter)); 4348 RUNTIME_ASSERT(IsValidAccessor(setter));
4349 CONVERT_SMI_ARG_CHECKED(unchecked, 4); 4349 CONVERT_SMI_ARG_CHECKED(unchecked, 4);
4350 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4350 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4351 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4351 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4352 4352
4353 // TODO(svenpanne) Define getter/setter/attributes in a single step. 4353 bool fast = obj->HasFastProperties();
4354 if (getter->IsNull() && setter->IsNull()) { 4354 JSObject::DefineAccessor(obj, name, getter, setter, attr);
4355 JSArray* array; 4355 if (fast) JSObject::TransformToFastProperties(obj, 0);
4356 { MaybeObject* maybe_array = GetOwnProperty(isolate, obj, name);
4357 if (!maybe_array->To(&array)) return maybe_array;
4358 }
4359 Object* current = FixedArray::cast(array->elements())->get(GETTER_INDEX);
4360 getter = Handle<Object>(current, isolate);
4361 }
4362 if (!getter->IsNull()) {
4363 MaybeObject* ok =
4364 obj->DefineAccessor(*name, ACCESSOR_GETTER, *getter, attr);
4365 if (ok->IsFailure()) return ok;
4366 }
4367 if (!setter->IsNull()) {
4368 MaybeObject* ok =
4369 obj->DefineAccessor(*name, ACCESSOR_SETTER, *setter, attr);
4370 if (ok->IsFailure()) return ok;
4371 }
4372
4373 return isolate->heap()->undefined_value(); 4356 return isolate->heap()->undefined_value();
4374 } 4357 }
4375 4358
4376 // Implements part of 8.12.9 DefineOwnProperty. 4359 // Implements part of 8.12.9 DefineOwnProperty.
4377 // There are 3 cases that lead here: 4360 // There are 3 cases that lead here:
4378 // Step 4a - define a new data property. 4361 // Step 4a - define a new data property.
4379 // Steps 9b & 12 - replace an existing accessor property with a data property. 4362 // Steps 9b & 12 - replace an existing accessor property with a data property.
4380 // Step 12 - update an existing data property with a data or generic 4363 // Step 12 - update an existing data property with a data or generic
4381 // descriptor. 4364 // descriptor.
4382 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { 4365 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
(...skipping 5833 matching lines...) Expand 10 before | Expand all | Expand 10 after
10216 // getter and/or setter. 10199 // getter and/or setter.
10217 bool hasJavaScriptAccessors = result_type == CALLBACKS && 10200 bool hasJavaScriptAccessors = result_type == CALLBACKS &&
10218 result_callback_obj->IsAccessorPair(); 10201 result_callback_obj->IsAccessorPair();
10219 Handle<FixedArray> details = 10202 Handle<FixedArray> details =
10220 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); 10203 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2);
10221 details->set(0, *value); 10204 details->set(0, *value);
10222 details->set(1, property_details); 10205 details->set(1, property_details);
10223 if (hasJavaScriptAccessors) { 10206 if (hasJavaScriptAccessors) {
10224 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); 10207 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj);
10225 details->set(2, isolate->heap()->ToBoolean(caught_exception)); 10208 details->set(2, isolate->heap()->ToBoolean(caught_exception));
10226 details->set(3, accessors->SafeGet(ACCESSOR_GETTER)); 10209 details->set(3, accessors->GetComponent(ACCESSOR_GETTER));
10227 details->set(4, accessors->SafeGet(ACCESSOR_SETTER)); 10210 details->set(4, accessors->GetComponent(ACCESSOR_SETTER));
10228 } 10211 }
10229 10212
10230 return *isolate->factory()->NewJSArrayWithElements(details); 10213 return *isolate->factory()->NewJSArrayWithElements(details);
10231 } 10214 }
10232 if (i < length - 1) { 10215 if (i < length - 1) {
10233 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); 10216 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype()));
10234 } 10217 }
10235 } 10218 }
10236 10219
10237 return isolate->heap()->undefined_value(); 10220 return isolate->heap()->undefined_value();
(...skipping 3124 matching lines...) Expand 10 before | Expand all | Expand 10 after
13362 // Handle last resort GC and make sure to allow future allocations 13345 // Handle last resort GC and make sure to allow future allocations
13363 // to grow the heap without causing GCs (if possible). 13346 // to grow the heap without causing GCs (if possible).
13364 isolate->counters()->gc_last_resort_from_js()->Increment(); 13347 isolate->counters()->gc_last_resort_from_js()->Increment();
13365 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13348 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13366 "Runtime::PerformGC"); 13349 "Runtime::PerformGC");
13367 } 13350 }
13368 } 13351 }
13369 13352
13370 13353
13371 } } // namespace v8::internal 13354 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698