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

Side by Side Diff: src/objects.cc

Issue 183683022: Enable Object.observe by default (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: add back use strict 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 2181 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 } else { 2192 } else {
2193 // Normalize the object to prevent very large instance descriptors. 2193 // Normalize the object to prevent very large instance descriptors.
2194 // This eliminates unwanted N^2 allocation and lookup behavior. 2194 // This eliminates unwanted N^2 allocation and lookup behavior.
2195 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 2195 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
2196 AddSlowProperty(object, name, value, attributes); 2196 AddSlowProperty(object, name, value, attributes);
2197 } 2197 }
2198 } else { 2198 } else {
2199 AddSlowProperty(object, name, value, attributes); 2199 AddSlowProperty(object, name, value, attributes);
2200 } 2200 }
2201 2201
2202 if (FLAG_harmony_observation && 2202 if (object->map()->is_observed() &&
2203 object->map()->is_observed() &&
2204 *name != isolate->heap()->hidden_string()) { 2203 *name != isolate->heap()->hidden_string()) {
2205 Handle<Object> old_value = isolate->factory()->the_hole_value(); 2204 Handle<Object> old_value = isolate->factory()->the_hole_value();
2206 EnqueueChangeRecord(object, "add", name, old_value); 2205 EnqueueChangeRecord(object, "add", name, old_value);
2207 } 2206 }
2208 2207
2209 return value; 2208 return value;
2210 } 2209 }
2211 2210
2212 2211
2213 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, 2212 void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
(...skipping 1869 matching lines...) Expand 10 before | Expand all | Expand 10 after
4083 Handle<Object> error = isolate->factory()->NewTypeError( 4082 Handle<Object> error = isolate->factory()->NewTypeError(
4084 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); 4083 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)));
4085 isolate->Throw(*error); 4084 isolate->Throw(*error);
4086 return Handle<Object>(); 4085 return Handle<Object>();
4087 } else { 4086 } else {
4088 return value; 4087 return value;
4089 } 4088 }
4090 } 4089 }
4091 4090
4092 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4091 Handle<Object> old_value = isolate->factory()->the_hole_value();
4093 bool is_observed = FLAG_harmony_observation && 4092 bool is_observed = object->map()->is_observed() &&
4094 object->map()->is_observed() &&
4095 *name != isolate->heap()->hidden_string(); 4093 *name != isolate->heap()->hidden_string();
4096 if (is_observed && lookup->IsDataProperty()) { 4094 if (is_observed && lookup->IsDataProperty()) {
4097 old_value = Object::GetProperty(object, name); 4095 old_value = Object::GetProperty(object, name);
4098 } 4096 }
4099 4097
4100 // This is a real property that is not read-only, or it is a 4098 // This is a real property that is not read-only, or it is a
4101 // transition or null descriptor and there are no setters in the prototypes. 4099 // transition or null descriptor and there are no setters in the prototypes.
4102 Handle<Object> result = value; 4100 Handle<Object> result = value;
4103 switch (lookup->type()) { 4101 switch (lookup->type()) {
4104 case NORMAL: 4102 case NORMAL:
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 object->map()->LookupTransition(*object, *name, &lookup); 4204 object->map()->LookupTransition(*object, *name, &lookup);
4207 TransitionFlag flag = lookup.IsFound() 4205 TransitionFlag flag = lookup.IsFound()
4208 ? OMIT_TRANSITION : INSERT_TRANSITION; 4206 ? OMIT_TRANSITION : INSERT_TRANSITION;
4209 // Neither properties nor transitions found. 4207 // Neither properties nor transitions found.
4210 return AddProperty(object, name, value, attributes, kNonStrictMode, 4208 return AddProperty(object, name, value, attributes, kNonStrictMode,
4211 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag); 4209 MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode, flag);
4212 } 4210 }
4213 4211
4214 Handle<Object> old_value = isolate->factory()->the_hole_value(); 4212 Handle<Object> old_value = isolate->factory()->the_hole_value();
4215 PropertyAttributes old_attributes = ABSENT; 4213 PropertyAttributes old_attributes = ABSENT;
4216 bool is_observed = FLAG_harmony_observation && 4214 bool is_observed = object->map()->is_observed() &&
4217 object->map()->is_observed() &&
4218 *name != isolate->heap()->hidden_string(); 4215 *name != isolate->heap()->hidden_string();
4219 if (is_observed && lookup.IsProperty()) { 4216 if (is_observed && lookup.IsProperty()) {
4220 if (lookup.IsDataProperty()) old_value = 4217 if (lookup.IsDataProperty()) old_value =
4221 Object::GetProperty(object, name); 4218 Object::GetProperty(object, name);
4222 old_attributes = lookup.GetAttributes(); 4219 old_attributes = lookup.GetAttributes();
4223 } 4220 }
4224 4221
4225 // Check of IsReadOnly removed from here in clone. 4222 // Check of IsReadOnly removed from here in clone.
4226 switch (lookup.type()) { 4223 switch (lookup.type()) {
4227 case NORMAL: 4224 case NORMAL:
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
5189 5186
5190 if (object->IsJSGlobalProxy()) { 5187 if (object->IsJSGlobalProxy()) {
5191 Handle<Object> proto(object->GetPrototype(), isolate); 5188 Handle<Object> proto(object->GetPrototype(), isolate);
5192 if (proto->IsNull()) return factory->false_value(); 5189 if (proto->IsNull()) return factory->false_value();
5193 ASSERT(proto->IsJSGlobalObject()); 5190 ASSERT(proto->IsJSGlobalObject());
5194 return DeleteElement(Handle<JSObject>::cast(proto), index, mode); 5191 return DeleteElement(Handle<JSObject>::cast(proto), index, mode);
5195 } 5192 }
5196 5193
5197 Handle<Object> old_value; 5194 Handle<Object> old_value;
5198 bool should_enqueue_change_record = false; 5195 bool should_enqueue_change_record = false;
5199 if (FLAG_harmony_observation && object->map()->is_observed()) { 5196 if (object->map()->is_observed()) {
5200 should_enqueue_change_record = HasLocalElement(object, index); 5197 should_enqueue_change_record = HasLocalElement(object, index);
5201 if (should_enqueue_change_record) { 5198 if (should_enqueue_change_record) {
5202 old_value = object->GetLocalElementAccessorPair(index) != NULL 5199 old_value = object->GetLocalElementAccessorPair(index) != NULL
5203 ? Handle<Object>::cast(factory->the_hole_value()) 5200 ? Handle<Object>::cast(factory->the_hole_value())
5204 : Object::GetElement(isolate, object, index); 5201 : Object::GetElement(isolate, object, index);
5205 } 5202 }
5206 } 5203 }
5207 5204
5208 // Skip interceptor if forcing deletion. 5205 // Skip interceptor if forcing deletion.
5209 Handle<Object> result; 5206 Handle<Object> result;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5260 Handle<Object> args[2] = { name, object }; 5257 Handle<Object> args[2] = { name, object };
5261 Handle<Object> error = isolate->factory()->NewTypeError( 5258 Handle<Object> error = isolate->factory()->NewTypeError(
5262 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args))); 5259 "strict_delete_property", HandleVector(args, ARRAY_SIZE(args)));
5263 isolate->Throw(*error); 5260 isolate->Throw(*error);
5264 return Handle<Object>(); 5261 return Handle<Object>();
5265 } 5262 }
5266 return isolate->factory()->false_value(); 5263 return isolate->factory()->false_value();
5267 } 5264 }
5268 5265
5269 Handle<Object> old_value = isolate->factory()->the_hole_value(); 5266 Handle<Object> old_value = isolate->factory()->the_hole_value();
5270 bool is_observed = FLAG_harmony_observation && 5267 bool is_observed = object->map()->is_observed() &&
5271 object->map()->is_observed() &&
5272 *name != isolate->heap()->hidden_string(); 5268 *name != isolate->heap()->hidden_string();
5273 if (is_observed && lookup.IsDataProperty()) { 5269 if (is_observed && lookup.IsDataProperty()) {
5274 old_value = Object::GetProperty(object, name); 5270 old_value = Object::GetProperty(object, name);
5275 } 5271 }
5276 Handle<Object> result; 5272 Handle<Object> result;
5277 5273
5278 // Check for interceptor. 5274 // Check for interceptor.
5279 if (lookup.IsInterceptor()) { 5275 if (lookup.IsInterceptor()) {
5280 // Skip interceptor if forcing a deletion. 5276 // Skip interceptor if forcing a deletion.
5281 if (mode == FORCE_DELETION) { 5277 if (mode == FORCE_DELETION) {
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
5497 5493
5498 // Do a map transition, other objects with this map may still 5494 // Do a map transition, other objects with this map may still
5499 // be extensible. 5495 // be extensible.
5500 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. 5496 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
5501 Handle<Map> new_map = Map::Copy(handle(object->map())); 5497 Handle<Map> new_map = Map::Copy(handle(object->map()));
5502 5498
5503 new_map->set_is_extensible(false); 5499 new_map->set_is_extensible(false);
5504 object->set_map(*new_map); 5500 object->set_map(*new_map);
5505 ASSERT(!object->map()->is_extensible()); 5501 ASSERT(!object->map()->is_extensible());
5506 5502
5507 if (FLAG_harmony_observation && object->map()->is_observed()) { 5503 if (object->map()->is_observed()) {
5508 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), 5504 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
5509 isolate->factory()->the_hole_value()); 5505 isolate->factory()->the_hole_value());
5510 } 5506 }
5511 return object; 5507 return object;
5512 } 5508 }
5513 5509
5514 5510
5515 template<typename Dictionary> 5511 template<typename Dictionary>
5516 static void FreezeDictionary(Dictionary* dictionary) { 5512 static void FreezeDictionary(Dictionary* dictionary) {
5517 int capacity = dictionary->Capacity(); 5513 int capacity = dictionary->Capacity();
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
6354 6350
6355 // Try to flatten before operating on the string. 6351 // Try to flatten before operating on the string.
6356 if (name->IsString()) String::cast(*name)->TryFlatten(); 6352 if (name->IsString()) String::cast(*name)->TryFlatten();
6357 6353
6358 if (!object->CanSetCallback(*name)) return; 6354 if (!object->CanSetCallback(*name)) return;
6359 6355
6360 uint32_t index = 0; 6356 uint32_t index = 0;
6361 bool is_element = name->AsArrayIndex(&index); 6357 bool is_element = name->AsArrayIndex(&index);
6362 6358
6363 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6359 Handle<Object> old_value = isolate->factory()->the_hole_value();
6364 bool is_observed = FLAG_harmony_observation && 6360 bool is_observed = object->map()->is_observed() &&
6365 object->map()->is_observed() &&
6366 *name != isolate->heap()->hidden_string(); 6361 *name != isolate->heap()->hidden_string();
6367 bool preexists = false; 6362 bool preexists = false;
6368 if (is_observed) { 6363 if (is_observed) {
6369 if (is_element) { 6364 if (is_element) {
6370 preexists = HasLocalElement(object, index); 6365 preexists = HasLocalElement(object, index);
6371 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { 6366 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6372 old_value = Object::GetElement(isolate, object, index); 6367 old_value = Object::GetElement(isolate, object, index);
6373 } 6368 }
6374 } else { 6369 } else {
6375 LookupResult lookup(isolate); 6370 LookupResult lookup(isolate);
(...skipping 5039 matching lines...) Expand 10 before | Expand all | Expand 10 after
11415 Handle<JSFunction>(isolate->observers_end_perform_splice()), 11410 Handle<JSFunction>(isolate->observers_end_perform_splice()),
11416 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args, 11411 isolate->factory()->undefined_value(), ARRAY_SIZE(args), args,
11417 &threw); 11412 &threw);
11418 ASSERT(!threw); 11413 ASSERT(!threw);
11419 } 11414 }
11420 11415
11421 11416
11422 MaybeObject* JSArray::SetElementsLength(Object* len) { 11417 MaybeObject* JSArray::SetElementsLength(Object* len) {
11423 // We should never end in here with a pixel or external array. 11418 // We should never end in here with a pixel or external array.
11424 ASSERT(AllowsSetElementsLength()); 11419 ASSERT(AllowsSetElementsLength());
11425 if (!(FLAG_harmony_observation && map()->is_observed())) 11420 if (!map()->is_observed())
11426 return GetElementsAccessor()->SetLength(this, len); 11421 return GetElementsAccessor()->SetLength(this, len);
11427 11422
11428 Isolate* isolate = GetIsolate(); 11423 Isolate* isolate = GetIsolate();
11429 HandleScope scope(isolate); 11424 HandleScope scope(isolate);
11430 Handle<JSArray> self(this); 11425 Handle<JSArray> self(this);
11431 List<uint32_t> indices; 11426 List<uint32_t> indices;
11432 List<Handle<Object> > old_values; 11427 List<Handle<Object> > old_values;
11433 Handle<Object> old_length_handle(self->length(), isolate); 11428 Handle<Object> old_length_handle(self->length(), isolate);
11434 Handle<Object> new_length_handle(len, isolate); 11429 Handle<Object> new_length_handle(len, isolate);
11435 uint32_t old_length = 0; 11430 uint32_t old_length = 0;
(...skipping 1110 matching lines...) Expand 10 before | Expand all | Expand 10 after
12546 return Handle<Object>(); 12541 return Handle<Object>();
12547 } 12542 }
12548 12543
12549 // Normalize the elements to enable attributes on the property. 12544 // Normalize the elements to enable attributes on the property.
12550 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { 12545 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) {
12551 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 12546 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
12552 // Make sure that we never go back to fast case. 12547 // Make sure that we never go back to fast case.
12553 dictionary->set_requires_slow_elements(); 12548 dictionary->set_requires_slow_elements();
12554 } 12549 }
12555 12550
12556 if (!(FLAG_harmony_observation && object->map()->is_observed())) { 12551 if (!object->map()->is_observed()) {
12557 return object->HasIndexedInterceptor() 12552 return object->HasIndexedInterceptor()
12558 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, 12553 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode,
12559 check_prototype, 12554 check_prototype,
12560 set_mode) 12555 set_mode)
12561 : SetElementWithoutInterceptor(object, index, value, attributes, 12556 : SetElementWithoutInterceptor(object, index, value, attributes,
12562 strict_mode, 12557 strict_mode,
12563 check_prototype, 12558 check_prototype,
12564 set_mode); 12559 set_mode);
12565 } 12560 }
12566 12561
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
13147 13142
13148 bool JSObject::ShouldConvertToFastElements() { 13143 bool JSObject::ShouldConvertToFastElements() {
13149 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 13144 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
13150 // If the elements are sparse, we should not go back to fast case. 13145 // If the elements are sparse, we should not go back to fast case.
13151 if (!HasDenseElements()) return false; 13146 if (!HasDenseElements()) return false;
13152 // An object requiring access checks is never allowed to have fast 13147 // An object requiring access checks is never allowed to have fast
13153 // elements. If it had fast elements we would skip security checks. 13148 // elements. If it had fast elements we would skip security checks.
13154 if (IsAccessCheckNeeded()) return false; 13149 if (IsAccessCheckNeeded()) return false;
13155 // Observed objects may not go to fast mode because they rely on map checks, 13150 // Observed objects may not go to fast mode because they rely on map checks,
13156 // and for fast element accesses we sometimes check element kinds only. 13151 // and for fast element accesses we sometimes check element kinds only.
13157 if (FLAG_harmony_observation && map()->is_observed()) return false; 13152 if (map()->is_observed()) return false;
13158 13153
13159 FixedArray* elements = FixedArray::cast(this->elements()); 13154 FixedArray* elements = FixedArray::cast(this->elements());
13160 SeededNumberDictionary* dictionary = NULL; 13155 SeededNumberDictionary* dictionary = NULL;
13161 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { 13156 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
13162 dictionary = SeededNumberDictionary::cast(elements->get(1)); 13157 dictionary = SeededNumberDictionary::cast(elements->get(1));
13163 } else { 13158 } else {
13164 dictionary = SeededNumberDictionary::cast(elements); 13159 dictionary = SeededNumberDictionary::cast(elements);
13165 } 13160 }
13166 // If an element has been added at a very high index in the elements 13161 // If an element has been added at a very high index in the elements
13167 // dictionary, we cannot go back to fast case. 13162 // dictionary, we cannot go back to fast case.
(...skipping 3334 matching lines...) Expand 10 before | Expand all | Expand 10 after
16502 #define ERROR_MESSAGES_TEXTS(C, T) T, 16497 #define ERROR_MESSAGES_TEXTS(C, T) T,
16503 static const char* error_messages_[] = { 16498 static const char* error_messages_[] = {
16504 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16499 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16505 }; 16500 };
16506 #undef ERROR_MESSAGES_TEXTS 16501 #undef ERROR_MESSAGES_TEXTS
16507 return error_messages_[reason]; 16502 return error_messages_[reason];
16508 } 16503 }
16509 16504
16510 16505
16511 } } // namespace v8::internal 16506 } } // 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