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

Side by Side Diff: src/objects.cc

Issue 198383002: Reland "Enable Object.observe by default" again (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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/object-observe.js ('k') | src/runtime.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 2163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2174 } else { 2174 } else {
2175 // Normalize the object to prevent very large instance descriptors. 2175 // Normalize the object to prevent very large instance descriptors.
2176 // This eliminates unwanted N^2 allocation and lookup behavior. 2176 // This eliminates unwanted N^2 allocation and lookup behavior.
2177 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 2177 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2178 AddSlowProperty(object, name, value, attributes); 2178 AddSlowProperty(object, name, value, attributes);
2179 } 2179 }
2180 } else { 2180 } else {
2181 AddSlowProperty(object, name, value, attributes); 2181 AddSlowProperty(object, name, value, attributes);
2182 } 2182 }
2183 2183
2184 if (FLAG_harmony_observation && 2184 if (object->map()->is_observed() &&
2185 object->map()->is_observed() &&
2186 *name != isolate->heap()->hidden_string()) { 2185 *name != isolate->heap()->hidden_string()) {
2187 Handle<Object> old_value = isolate->factory()->the_hole_value(); 2186 Handle<Object> old_value = isolate->factory()->the_hole_value();
2188 EnqueueChangeRecord(object, "add", name, old_value); 2187 EnqueueChangeRecord(object, "add", name, old_value);
2189 } 2188 }
2190 2189
2191 return value; 2190 return value;
2192 } 2191 }
2193 2192
2194 2193
2195 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2194 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
(...skipping 1877 matching lines...) Expand 10 before | Expand all | Expand 10 after
4073 Handle<Object> error = isolate->factory()->NewTypeError( 4072 Handle<Object> error = isolate->factory()->NewTypeError(
4074 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 4073 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
4075 isolate->Throw(*error); 4074 isolate->Throw(*error);
4076 return Handle<Object>(); 4075 return Handle<Object>();
4077 } else { 4076 } else {
4078 return value; 4077 return value;
4079 } 4078 }
4080 } 4079 }
4081 4080
4082 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4081 Handle<Object> old_value = isolate->factory()->the_hole_value();
4083 bool is_observed = FLAG_harmony_observation && 4082 bool is_observed = object->map()->is_observed() &&
4084 object->map()->is_observed() &&
4085 *name != isolate->heap()->hidden_string(); 4083 *name != isolate->heap()->hidden_string();
4086 if (is_observed && lookup->IsDataProperty()) { 4084 if (is_observed && lookup->IsDataProperty()) {
4087 old_value = Object::GetProperty(object, name); 4085 old_value = Object::GetProperty(object, name);
4088 } 4086 }
4089 4087
4090 // This is a real property that is not read-only, or it is a 4088 // This is a real property that is not read-only, or it is a
4091 // transition or null descriptor and there are no setters in the prototypes. 4089 // transition or null descriptor and there are no setters in the prototypes.
4092 Handle<Object> result = value; 4090 Handle<Object> result = value;
4093 switch (lookup->type()) { 4091 switch (lookup->type()) {
4094 case NORMAL: 4092 case NORMAL:
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4196 object->map()->LookupTransition(*object, *name, &lookup); 4194 object->map()->LookupTransition(*object, *name, &lookup);
4197 TransitionFlag flag = lookup.IsFound() 4195 TransitionFlag flag = lookup.IsFound()
4198 ? OMIT_TRANSITION : INSERT_TRANSITION; 4196 ? OMIT_TRANSITION : INSERT_TRANSITION;
4199 // Neither properties nor transitions found. 4197 // Neither properties nor transitions found.
4200 return AddProperty(object, name, value, attributes, SLOPPY, 4198 return AddProperty(object, name, value, attributes, SLOPPY,
4201 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); 4199 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
4202 } 4200 }
4203 4201
4204 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4202 Handle<Object> old_value = isolate->factory()->the_hole_value();
4205 PropertyAttributes old_attributes = ABSENT; 4203 PropertyAttributes old_attributes = ABSENT;
4206 bool is_observed = FLAG_harmony_observation && 4204 bool is_observed = object->map()->is_observed() &&
4207 object->map()->is_observed() &&
4208 *name != isolate->heap()->hidden_string(); 4205 *name != isolate->heap()->hidden_string();
4209 if (is_observed && lookup.IsProperty()) { 4206 if (is_observed && lookup.IsProperty()) {
4210 if (lookup.IsDataProperty()) old_value = 4207 if (lookup.IsDataProperty()) old_value =
4211 Object::GetProperty(object, name); 4208 Object::GetProperty(object, name);
4212 old_attributes = lookup.GetAttributes(); 4209 old_attributes = lookup.GetAttributes();
4213 } 4210 }
4214 4211
4215 // Check of IsReadOnly removed from here in clone. 4212 // Check of IsReadOnly removed from here in clone.
4216 switch (lookup.type()) { 4213 switch (lookup.type()) {
4217 case NORMAL: 4214 case NORMAL:
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
5180 5177
5181 if (object->IsJSGlobalProxy()) { 5178 if (object->IsJSGlobalProxy()) {
5182 Handle<Object> proto(object->GetPrototype(), isolate); 5179 Handle<Object> proto(object->GetPrototype(), isolate);
5183 if (proto->IsNull()) return factory->false_value(); 5180 if (proto->IsNull()) return factory->false_value();
5184 ASSERT(proto->IsJSGlobalObject()); 5181 ASSERT(proto->IsJSGlobalObject());
5185 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); 5182 return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
5186 } 5183 }
5187 5184
5188 Handle<Object> old_value; 5185 Handle<Object> old_value;
5189 bool should_enqueue_change_record = false; 5186 bool should_enqueue_change_record = false;
5190 if (FLAG_harmony_observation && object->map()->is_observed()) { 5187 if (object->map()->is_observed()) {
5191 should_enqueue_change_record = HasLocalElement(object, index); 5188 should_enqueue_change_record = HasLocalElement(object, index);
5192 if (should_enqueue_change_record) { 5189 if (should_enqueue_change_record) {
5193 old_value = object->GetLocalElementAccessorPair(index) != NULL 5190 old_value = object->GetLocalElementAccessorPair(index) != NULL
5194 ? Handle<Object>::cast(factory->the_hole_value()) 5191 ? Handle<Object>::cast(factory->the_hole_value())
5195 : Object::GetElement(isolate, object, index); 5192 : Object::GetElement(isolate, object, index);
5196 } 5193 }
5197 } 5194 }
5198 5195
5199 // Skip interceptor if forcing deletion. 5196 // Skip interceptor if forcing deletion.
5200 Handle<Object> result; 5197 Handle<Object> result;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5251 Handle<Object> args[2] = { name, object }; 5248 Handle<Object> args[2] = { name, object };
5252 Handle<Object> error = isolate->factory()->NewTypeError( 5249 Handle<Object> error = isolate->factory()->NewTypeError(
5253 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); 5250 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args)));
5254 isolate->Throw(*error); 5251 isolate->Throw(*error);
5255 return Handle<Object>(); 5252 return Handle<Object>();
5256 } 5253 }
5257 return isolate->factory()->false_value(); 5254 return isolate->factory()->false_value();
5258 } 5255 }
5259 5256
5260 Handle<Object> old_value = isolate->factory()->the_hole_value(); 5257 Handle<Object> old_value = isolate->factory()->the_hole_value();
5261 bool is_observed = FLAG_harmony_observation && 5258 bool is_observed = object->map()->is_observed() &&
5262 object->map()->is_observed() &&
5263 *name != isolate->heap()->hidden_string(); 5259 *name != isolate->heap()->hidden_string();
5264 if (is_observed && lookup.IsDataProperty()) { 5260 if (is_observed && lookup.IsDataProperty()) {
5265 old_value = Object::GetProperty(object, name); 5261 old_value = Object::GetProperty(object, name);
5266 } 5262 }
5267 Handle<Object> result; 5263 Handle<Object> result;
5268 5264
5269 // Check for interceptor. 5265 // Check for interceptor.
5270 if (lookup.IsInterceptor()) { 5266 if (lookup.IsInterceptor()) {
5271 // Skip interceptor if forcing a deletion. 5267 // Skip interceptor if forcing a deletion.
5272 if (mode == FORCE_DELETION) { 5268 if (mode == FORCE_DELETION) {
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
5488 5484
5489 // Do a map transition, other objects with this map may still 5485 // Do a map transition, other objects with this map may still
5490 // be extensible. 5486 // be extensible.
5491 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 5487 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5492 Handle<Map> new_map = Map::Copy(handle(object->map())); 5488 Handle<Map> new_map = Map::Copy(handle(object->map()));
5493 5489
5494 new_map->set_is_extensible(false); 5490 new_map->set_is_extensible(false);
5495 JSObject::MigrateToMap(object, new_map); 5491 JSObject::MigrateToMap(object, new_map);
5496 ASSERT(!object->map()->is_extensible()); 5492 ASSERT(!object->map()->is_extensible());
5497 5493
5498 if (FLAG_harmony_observation && object->map()->is_observed()) { 5494 if (object->map()->is_observed()) {
5499 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), 5495 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
5500 isolate->factory()->the_hole_value()); 5496 isolate->factory()->the_hole_value());
5501 } 5497 }
5502 return object; 5498 return object;
5503 } 5499 }
5504 5500
5505 5501
5506 template<typename Dictionary> 5502 template<typename Dictionary>
5507 static void FreezeDictionary(Dictionary* dictionary) { 5503 static void FreezeDictionary(Dictionary* dictionary) {
5508 int capacity = dictionary->Capacity(); 5504 int capacity = dictionary->Capacity();
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
6346 6342
6347 // Try to flatten before operating on the string. 6343 // Try to flatten before operating on the string.
6348 if (name->IsString()) String::cast(*name)->TryFlatten(); 6344 if (name->IsString()) String::cast(*name)->TryFlatten();
6349 6345
6350 if (!JSObject::CanSetCallback(object, name)) return; 6346 if (!JSObject::CanSetCallback(object, name)) return;
6351 6347
6352 uint32_t index = 0; 6348 uint32_t index = 0;
6353 bool is_element = name->AsArrayIndex(&index); 6349 bool is_element = name->AsArrayIndex(&index);
6354 6350
6355 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6351 Handle<Object> old_value = isolate->factory()->the_hole_value();
6356 bool is_observed = FLAG_harmony_observation && 6352 bool is_observed = object->map()->is_observed() &&
6357 object->map()->is_observed() &&
6358 *name != isolate->heap()->hidden_string(); 6353 *name != isolate->heap()->hidden_string();
6359 bool preexists = false; 6354 bool preexists = false;
6360 if (is_observed) { 6355 if (is_observed) {
6361 if (is_element) { 6356 if (is_element) {
6362 preexists = HasLocalElement(object, index); 6357 preexists = HasLocalElement(object, index);
6363 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6358 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6364 old_value = Object::GetElement(isolate, object, index); 6359 old_value = Object::GetElement(isolate, object, index);
6365 } 6360 }
6366 } else { 6361 } else {
6367 LookupResult lookup(isolate); 6362 LookupResult lookup(isolate);
(...skipping 5040 matching lines...) Expand 10 before | Expand all | Expand 10 after
11408 Handle<JSFunction>(isolate->observers_end_perform_splice()), 11403 Handle<JSFunction>(isolate->observers_end_perform_splice()),
11409 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, 11404 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
11410 &threw); 11405 &threw);
11411 ASSERT(!threw); 11406 ASSERT(!threw);
11412 } 11407 }
11413 11408
11414 11409
11415 MaybeObject* JSArray::SetElementsLength(Object* len) { 11410 MaybeObject* JSArray::SetElementsLength(Object* len) {
11416 // We should never end in here with a pixel or external array. 11411 // We should never end in here with a pixel or external array.
11417 ASSERT(AllowsSetElementsLength()); 11412 ASSERT(AllowsSetElementsLength());
11418 if (!(FLAG_harmony_observation && map()->is_observed())) 11413 if (!map()->is_observed())
11419 return GetElementsAccessor()->SetLength(this, len); 11414 return GetElementsAccessor()->SetLength(this, len);
11420 11415
11421 Isolate* isolate = GetIsolate(); 11416 Isolate* isolate = GetIsolate();
11422 HandleScope scope(isolate); 11417 HandleScope scope(isolate);
11423 Handle<JSArray> self(this); 11418 Handle<JSArray> self(this);
11424 List<uint32_t> indices; 11419 List<uint32_t> indices;
11425 List<Handle<Object> > old_values; 11420 List<Handle<Object> > old_values;
11426 Handle<Object> old_length_handle(self->length(), isolate); 11421 Handle<Object> old_length_handle(self->length(), isolate);
11427 Handle<Object> new_length_handle(len, isolate); 11422 Handle<Object> new_length_handle(len, isolate);
11428 uint32_t old_length = 0; 11423 uint32_t old_length = 0;
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after
12537 return Handle<Object>(); 12532 return Handle<Object>();
12538 } 12533 }
12539 12534
12540 // Normalize the elements to enable attributes on the property. 12535 // Normalize the elements to enable attributes on the property.
12541 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { 12536 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) {
12542 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 12537 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
12543 // Make sure that we never go back to fast case. 12538 // Make sure that we never go back to fast case.
12544 dictionary->set_requires_slow_elements(); 12539 dictionary->set_requires_slow_elements();
12545 } 12540 }
12546 12541
12547 if (!(FLAG_harmony_observation && object->map()->is_observed())) { 12542 if (!object->map()->is_observed()) {
12548 return object->HasIndexedInterceptor() 12543 return object->HasIndexedInterceptor()
12549 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, 12544 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
12550 check_prototype, 12545 check_prototype,
12551 set_mode) 12546 set_mode)
12552 : SetElementWithoutInterceptor(object, index, value, attributes, 12547 : SetElementWithoutInterceptor(object, index, value, attributes,
12553 strict_mode, 12548 strict_mode,
12554 check_prototype, 12549 check_prototype,
12555 set_mode); 12550 set_mode);
12556 } 12551 }
12557 12552
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
13139 13134
13140 bool JSObject::ShouldConvertToFastElements() { 13135 bool JSObject::ShouldConvertToFastElements() {
13141 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 13136 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
13142 // If the elements are sparse, we should not go back to fast case. 13137 // If the elements are sparse, we should not go back to fast case.
13143 if (!HasDenseElements()) return false; 13138 if (!HasDenseElements()) return false;
13144 // An object requiring access checks is never allowed to have fast 13139 // An object requiring access checks is never allowed to have fast
13145 // elements. If it had fast elements we would skip security checks. 13140 // elements. If it had fast elements we would skip security checks.
13146 if (IsAccessCheckNeeded()) return false; 13141 if (IsAccessCheckNeeded()) return false;
13147 // Observed objects may not go to fast mode because they rely on map checks, 13142 // Observed objects may not go to fast mode because they rely on map checks,
13148 // and for fast element accesses we sometimes check element kinds only. 13143 // and for fast element accesses we sometimes check element kinds only.
13149 if (FLAG_harmony_observation && map()->is_observed()) return false; 13144 if (map()->is_observed()) return false;
13150 13145
13151 FixedArray* elements = FixedArray::cast(this->elements()); 13146 FixedArray* elements = FixedArray::cast(this->elements());
13152 SeededNumberDictionary* dictionary = NULL; 13147 SeededNumberDictionary* dictionary = NULL;
13153 if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) { 13148 if (elements->map() == GetHeap()->sloppy_arguments_elements_map()) {
13154 dictionary = SeededNumberDictionary::cast(elements->get(1)); 13149 dictionary = SeededNumberDictionary::cast(elements->get(1));
13155 } else { 13150 } else {
13156 dictionary = SeededNumberDictionary::cast(elements); 13151 dictionary = SeededNumberDictionary::cast(elements);
13157 } 13152 }
13158 // If an element has been added at a very high index in the elements 13153 // If an element has been added at a very high index in the elements
13159 // dictionary, we cannot go back to fast case. 13154 // dictionary, we cannot go back to fast case.
(...skipping 3320 matching lines...) Expand 10 before | Expand all | Expand 10 after
16480 #define ERROR_MESSAGES_TEXTS(C, T) T, 16475 #define ERROR_MESSAGES_TEXTS(C, T) T,
16481 static const char* error_messages_[] = { 16476 static const char* error_messages_[] = {
16482 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16477 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16483 }; 16478 };
16484 #undef ERROR_MESSAGES_TEXTS 16479 #undef ERROR_MESSAGES_TEXTS
16485 return error_messages_[reason]; 16480 return error_messages_[reason];
16486 } 16481 }
16487 16482
16488 16483
16489 } } // namespace v8::internal 16484 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/object-observe.js ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698