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

Side by Side Diff: src/objects.cc

Issue 11275283: Restructure JSObject::SetElement for performance. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month 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 | « no previous file | 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 10249 matching lines...) Expand 10 before | Expand all | Expand 10 after
10260 } 10260 }
10261 10261
10262 10262
10263 MaybeObject* JSObject::SetElement(uint32_t index, 10263 MaybeObject* JSObject::SetElement(uint32_t index,
10264 Object* value_raw, 10264 Object* value_raw,
10265 PropertyAttributes attributes, 10265 PropertyAttributes attributes,
10266 StrictModeFlag strict_mode, 10266 StrictModeFlag strict_mode,
10267 bool check_prototype, 10267 bool check_prototype,
10268 SetPropertyMode set_mode) { 10268 SetPropertyMode set_mode) {
10269 Isolate* isolate = GetIsolate(); 10269 Isolate* isolate = GetIsolate();
10270 HandleScope scope(isolate);
10271 Handle<JSObject> self(this);
10272 Handle<Object> value(value_raw);
10273 10270
10274 // Check access rights if needed. 10271 // Check access rights if needed.
10275 if (IsAccessCheckNeeded()) { 10272 if (IsAccessCheckNeeded()) {
10276 Heap* heap = GetHeap(); 10273 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) {
10277 if (!heap->isolate()->MayIndexedAccess(*self, index, v8::ACCESS_SET)) { 10274 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
10278 heap->isolate()->ReportFailedAccessCheck(*self, v8::ACCESS_SET); 10275 return value_raw;
10279 return *value;
10280 } 10276 }
10281 } 10277 }
10282 10278
10283 if (IsJSGlobalProxy()) { 10279 if (IsJSGlobalProxy()) {
10284 Object* proto = GetPrototype(); 10280 Object* proto = GetPrototype();
10285 if (proto->IsNull()) return *value; 10281 if (proto->IsNull()) return value_raw;
10286 ASSERT(proto->IsJSGlobalObject()); 10282 ASSERT(proto->IsJSGlobalObject());
10287 return JSObject::cast(proto)->SetElement(index, 10283 return JSObject::cast(proto)->SetElement(index,
10288 *value, 10284 value_raw,
10289 attributes, 10285 attributes,
10290 strict_mode, 10286 strict_mode,
10291 check_prototype, 10287 check_prototype,
10292 set_mode); 10288 set_mode);
10293 } 10289 }
10294 10290
10295 // Don't allow element properties to be redefined for external arrays. 10291 // Don't allow element properties to be redefined for external arrays.
10296 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { 10292 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) {
10297 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 10293 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
10298 Handle<Object> args[] = { self, number }; 10294 Handle<Object> args[] = { handle(this), number };
10299 Handle<Object> error = isolate->factory()->NewTypeError( 10295 Handle<Object> error = isolate->factory()->NewTypeError(
10300 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); 10296 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args)));
10301 return isolate->Throw(*error); 10297 return isolate->Throw(*error);
10302 } 10298 }
10303 10299
10304 // Normalize the elements to enable attributes on the property. 10300 // Normalize the elements to enable attributes on the property.
10305 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { 10301 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) {
10306 SeededNumberDictionary* dictionary; 10302 SeededNumberDictionary* dictionary;
10307 MaybeObject* maybe_object = NormalizeElements(); 10303 MaybeObject* maybe_object = NormalizeElements();
10308 if (!maybe_object->To(&dictionary)) return maybe_object; 10304 if (!maybe_object->To(&dictionary)) return maybe_object;
10309 // Make sure that we never go back to fast case. 10305 // Make sure that we never go back to fast case.
10310 dictionary->set_requires_slow_elements(); 10306 dictionary->set_requires_slow_elements();
10311 } 10307 }
10312 10308
10309 if (!(FLAG_harmony_observation && map()->is_observed())) {
10310 return HasIndexedInterceptor()
rafaelw 2012/11/13 13:18:44 consider factoring out into inline static?
Toon Verwaest 2012/11/13 13:38:08 +1 On 2012/11/13 13:18:44, rafaelw wrote:
rossberg 2012/11/13 13:47:44 Note that one version is handlified while the othe
rafaelw 2012/11/13 14:53:01 I'm not understanding why it wouldn't work, but I
rossberg 2012/11/13 15:33:13 Thing is, I could only factor it out in form of a
10311 ? SetElementWithInterceptor(
10312 index, value_raw, attributes, strict_mode, check_prototype, set_mode)
10313 : SetElementWithoutInterceptor(
10314 index, value_raw, attributes, strict_mode, check_prototype, set_mode);
10315 }
10316
10313 // From here on, everything has to be handlified. 10317 // From here on, everything has to be handlified.
10314 Handle<String> name; 10318 Handle<JSObject> self(this);
10315 Handle<Object> old_value(isolate->heap()->the_hole_value()); 10319 Handle<Object> value(value_raw);
10316 Handle<Object> old_array_length; 10320 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index);
10317 PropertyAttributes old_attributes = ABSENT; 10321 Handle<Object> old_value = isolate->factory()->the_hole_value();
10318 bool preexists = false; 10322 Handle<Object> old_length;
10319 if (FLAG_harmony_observation && map()->is_observed()) { 10323
10320 name = isolate->factory()->Uint32ToString(index); 10324 if (old_attributes != ABSENT) {
10321 preexists = self->HasLocalElement(index); 10325 // TODO(observe): only read & set old_value if we have a data property
10322 if (preexists) { 10326 old_value = Object::GetElement(self, index);
10323 old_attributes = self->GetLocalPropertyAttribute(*name); 10327 } else if (self->IsJSArray()) {
10324 // TODO(observe): only read & set old_value if we have a data property 10328 // Store old array length in case adding an element grows the array.
10325 old_value = Object::GetElement(self, index); 10329 old_length = handle(Handle<JSArray>::cast(self)->length());
10326 } else if (self->IsJSArray()) {
10327 // Store old array length in case adding an element grows the array.
10328 old_array_length = handle(Handle<JSArray>::cast(self)->length());
10329 }
10330 } 10330 }
10331 10331
10332 // Check for lookup interceptor 10332 // Check for lookup interceptor
10333 MaybeObject* result = self->HasIndexedInterceptor() 10333 MaybeObject* result = self->HasIndexedInterceptor()
10334 ? self->SetElementWithInterceptor( 10334 ? self->SetElementWithInterceptor(
10335 index, *value, attributes, strict_mode, check_prototype, set_mode) 10335 index, *value, attributes, strict_mode, check_prototype, set_mode)
10336 : self->SetElementWithoutInterceptor( 10336 : self->SetElementWithoutInterceptor(
10337 index, *value, attributes, strict_mode, check_prototype, set_mode); 10337 index, *value, attributes, strict_mode, check_prototype, set_mode);
10338 10338
10339 Handle<Object> hresult; 10339 Handle<Object> hresult;
10340 if (!result->ToHandle(&hresult)) return result; 10340 if (!result->ToHandle(&hresult)) return result;
10341 10341
10342 if (FLAG_harmony_observation && map()->is_observed()) { 10342 Handle<String> name = isolate->factory()->Uint32ToString(index);
10343 PropertyAttributes new_attributes = self->GetLocalPropertyAttribute(*name); 10343 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index);
10344 if (!preexists) { 10344 if (old_attributes == ABSENT) {
rafaelw 2012/11/13 13:18:44 nit: return early here. e.g. if (old_attributes !
Toon Verwaest 2012/11/13 13:38:08 This doesn't seem possible, given that the value i
rafaelw 2012/11/13 13:41:25 You are correct. Sorry. Misread the code. On 2012
10345 EnqueueChangeRecord(self, "new", name, old_value); 10345 EnqueueChangeRecord(self, "new", name, old_value);
10346 if (self->IsJSArray() && 10346 if (self->IsJSArray() &&
10347 !old_array_length->SameValue(Handle<JSArray>::cast(self)->length())) { 10347 !old_length->SameValue(Handle<JSArray>::cast(self)->length())) {
10348 EnqueueChangeRecord(self, "updated", 10348 EnqueueChangeRecord(
10349 isolate->factory()->length_symbol(), 10349 self, "updated", isolate->factory()->length_symbol(), old_length);
10350 old_array_length);
10351 }
10352 } else if (new_attributes != old_attributes || old_value->IsTheHole()) {
10353 EnqueueChangeRecord(self, "reconfigured", name, old_value);
10354 } else {
10355 Handle<Object> new_value = Object::GetElement(self, index);
10356 if (!new_value->SameValue(*old_value))
10357 EnqueueChangeRecord(self, "updated", name, old_value);
10358 } 10350 }
10351 } else if (old_attributes != new_attributes || old_value->IsTheHole()) {
10352 EnqueueChangeRecord(self, "reconfigured", name, old_value);
10353 } else if (!old_value->SameValue(*Object::GetElement(self, index))) {
10354 EnqueueChangeRecord(self, "updated", name, old_value);
10359 } 10355 }
10360 10356
10361 return *hresult; 10357 return *hresult;
10362 } 10358 }
10363 10359
10364 10360
10365 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 10361 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
10366 Object* value, 10362 Object* value,
10367 PropertyAttributes attr, 10363 PropertyAttributes attr,
10368 StrictModeFlag strict_mode, 10364 StrictModeFlag strict_mode,
(...skipping 3494 matching lines...) Expand 10 before | Expand all | Expand 10 after
13863 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 13859 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
13864 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 13860 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
13865 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 13861 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
13866 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 13862 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
13867 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 13863 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
13868 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 13864 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
13869 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 13865 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
13870 } 13866 }
13871 13867
13872 } } // namespace v8::internal 13868 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698