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

Side by Side Diff: src/objects.cc

Issue 11471028: Handlify JSObject::SetDictionaryElement, which may call back into JS. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment Created 8 years 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 10124 matching lines...) Expand 10 before | Expand all | Expand 10 after
10135 ASSERT(elements()->IsFixedArray()); 10135 ASSERT(elements()->IsFixedArray());
10136 backing_store->set(index, value); 10136 backing_store->set(index, value);
10137 if (must_update_array_length) { 10137 if (must_update_array_length) {
10138 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); 10138 JSArray::cast(this)->set_length(Smi::FromInt(array_length));
10139 } 10139 }
10140 return value; 10140 return value;
10141 } 10141 }
10142 10142
10143 10143
10144 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, 10144 MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
10145 Object* value, 10145 Object* value_raw,
10146 PropertyAttributes attributes, 10146 PropertyAttributes attributes,
10147 StrictModeFlag strict_mode, 10147 StrictModeFlag strict_mode,
10148 bool check_prototype, 10148 bool check_prototype,
10149 SetPropertyMode set_mode) { 10149 SetPropertyMode set_mode) {
10150 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 10150 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
10151 Isolate* isolate = GetIsolate(); 10151 Isolate* isolate = GetIsolate();
10152 Heap* heap = isolate->heap(); 10152 Heap* heap = isolate->heap();
10153 Handle<JSObject> self(this);
10154 Handle<Object> value(value_raw);
10153 10155
10154 // Insert element in the dictionary. 10156 // Insert element in the dictionary.
10155 FixedArray* elements = FixedArray::cast(this->elements()); 10157 Handle<FixedArray> elements(FixedArray::cast(this->elements()));
10156 bool is_arguments = 10158 bool is_arguments =
10157 (elements->map() == heap->non_strict_arguments_elements_map()); 10159 (elements->map() == heap->non_strict_arguments_elements_map());
10158 SeededNumberDictionary* dictionary = NULL; 10160 Handle<SeededNumberDictionary> dictionary(is_arguments
10159 if (is_arguments) { 10161 ? SeededNumberDictionary::cast(elements->get(1))
10160 dictionary = SeededNumberDictionary::cast(elements->get(1)); 10162 : SeededNumberDictionary::cast(*elements));
10161 } else {
10162 dictionary = SeededNumberDictionary::cast(elements);
10163 }
10164 10163
10165 int entry = dictionary->FindEntry(index); 10164 int entry = dictionary->FindEntry(index);
10166 if (entry != SeededNumberDictionary::kNotFound) { 10165 if (entry != SeededNumberDictionary::kNotFound) {
10167 Object* element = dictionary->ValueAt(entry); 10166 Object* element = dictionary->ValueAt(entry);
10168 PropertyDetails details = dictionary->DetailsAt(entry); 10167 PropertyDetails details = dictionary->DetailsAt(entry);
10169 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { 10168 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) {
10170 return SetElementWithCallback(element, index, value, this, strict_mode); 10169 return SetElementWithCallback(element, index, *value, this, strict_mode);
10171 } else { 10170 } else {
10172 dictionary->UpdateMaxNumberKey(index); 10171 dictionary->UpdateMaxNumberKey(index);
10173 // If a value has not been initialized we allow writing to it even if it 10172 // If a value has not been initialized we allow writing to it even if it
10174 // is read-only (a declared const that has not been initialized). If a 10173 // is read-only (a declared const that has not been initialized). If a
10175 // value is being defined we skip attribute checks completely. 10174 // value is being defined we skip attribute checks completely.
10176 if (set_mode == DEFINE_PROPERTY) { 10175 if (set_mode == DEFINE_PROPERTY) {
10177 details = PropertyDetails( 10176 details = PropertyDetails(
10178 attributes, NORMAL, details.dictionary_index()); 10177 attributes, NORMAL, details.dictionary_index());
10179 dictionary->DetailsAtPut(entry, details); 10178 dictionary->DetailsAtPut(entry, details);
10180 } else if (details.IsReadOnly() && !element->IsTheHole()) { 10179 } else if (details.IsReadOnly() && !element->IsTheHole()) {
10181 if (strict_mode == kNonStrictMode) { 10180 if (strict_mode == kNonStrictMode) {
10182 return isolate->heap()->undefined_value(); 10181 return isolate->heap()->undefined_value();
10183 } else { 10182 } else {
10184 Handle<Object> holder(this); 10183 Handle<Object> holder(this);
10185 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 10184 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
10186 Handle<Object> args[2] = { number, holder }; 10185 Handle<Object> args[2] = { number, holder };
10187 Handle<Object> error = 10186 Handle<Object> error =
10188 isolate->factory()->NewTypeError("strict_read_only_property", 10187 isolate->factory()->NewTypeError("strict_read_only_property",
10189 HandleVector(args, 2)); 10188 HandleVector(args, 2));
10190 return isolate->Throw(*error); 10189 return isolate->Throw(*error);
10191 } 10190 }
10192 } 10191 }
10193 // Elements of the arguments object in slow mode might be slow aliases. 10192 // Elements of the arguments object in slow mode might be slow aliases.
10194 if (is_arguments && element->IsAliasedArgumentsEntry()) { 10193 if (is_arguments && element->IsAliasedArgumentsEntry()) {
10195 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element); 10194 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(element);
10196 Context* context = Context::cast(elements->get(0)); 10195 Context* context = Context::cast(elements->get(0));
10197 int context_index = entry->aliased_context_slot(); 10196 int context_index = entry->aliased_context_slot();
10198 ASSERT(!context->get(context_index)->IsTheHole()); 10197 ASSERT(!context->get(context_index)->IsTheHole());
10199 context->set(context_index, value); 10198 context->set(context_index, *value);
10200 // For elements that are still writable we keep slow aliasing. 10199 // For elements that are still writable we keep slow aliasing.
10201 if (!details.IsReadOnly()) value = element; 10200 if (!details.IsReadOnly()) value = handle(element, isolate);
10202 } 10201 }
10203 dictionary->ValueAtPut(entry, value); 10202 dictionary->ValueAtPut(entry, *value);
10204 } 10203 }
10205 } else { 10204 } else {
10206 // Index not already used. Look for an accessor in the prototype chain. 10205 // Index not already used. Look for an accessor in the prototype chain.
10206 // Can cause GC!
10207 if (check_prototype) { 10207 if (check_prototype) {
10208 bool found; 10208 bool found;
10209 MaybeObject* result = 10209 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(
10210 SetElementWithCallbackSetterInPrototypes( 10210 index, *value, &found, strict_mode);
10211 index, value, &found, strict_mode);
10212 if (found) return result; 10211 if (found) return result;
10213 } 10212 }
10214 // When we set the is_extensible flag to false we always force the 10213 // When we set the is_extensible flag to false we always force the
10215 // element into dictionary mode (and force them to stay there). 10214 // element into dictionary mode (and force them to stay there).
10216 if (!map()->is_extensible()) { 10215 if (!self->map()->is_extensible()) {
10217 if (strict_mode == kNonStrictMode) { 10216 if (strict_mode == kNonStrictMode) {
10218 return isolate->heap()->undefined_value(); 10217 return isolate->heap()->undefined_value();
10219 } else { 10218 } else {
10220 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 10219 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
10221 Handle<String> name = isolate->factory()->NumberToString(number); 10220 Handle<String> name = isolate->factory()->NumberToString(number);
10222 Handle<Object> args[1] = { name }; 10221 Handle<Object> args[1] = { name };
10223 Handle<Object> error = 10222 Handle<Object> error =
10224 isolate->factory()->NewTypeError("object_not_extensible", 10223 isolate->factory()->NewTypeError("object_not_extensible",
10225 HandleVector(args, 1)); 10224 HandleVector(args, 1));
10226 return isolate->Throw(*error); 10225 return isolate->Throw(*error);
10227 } 10226 }
10228 } 10227 }
10229 FixedArrayBase* new_dictionary; 10228 FixedArrayBase* new_dictionary;
10230 PropertyDetails details = PropertyDetails(attributes, NORMAL); 10229 PropertyDetails details = PropertyDetails(attributes, NORMAL);
10231 MaybeObject* maybe = dictionary->AddNumberEntry(index, value, details); 10230 MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details);
10232 if (!maybe->To(&new_dictionary)) return maybe; 10231 if (!maybe->To(&new_dictionary)) return maybe;
10233 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { 10232 if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) {
10234 if (is_arguments) { 10233 if (is_arguments) {
10235 elements->set(1, new_dictionary); 10234 elements->set(1, new_dictionary);
10236 } else { 10235 } else {
10237 set_elements(new_dictionary); 10236 self->set_elements(new_dictionary);
10238 } 10237 }
10239 dictionary = SeededNumberDictionary::cast(new_dictionary); 10238 dictionary =
10239 handle(SeededNumberDictionary::cast(new_dictionary), isolate);
10240 } 10240 }
10241 } 10241 }
10242 10242
10243 // Update the array length if this JSObject is an array. 10243 // Update the array length if this JSObject is an array.
10244 if (IsJSArray()) { 10244 if (self->IsJSArray()) {
10245 MaybeObject* result = 10245 MaybeObject* result =
10246 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); 10246 JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value);
10247 if (result->IsFailure()) return result; 10247 if (result->IsFailure()) return result;
10248 } 10248 }
10249 10249
10250 // Attempt to put this object back in fast case. 10250 // Attempt to put this object back in fast case.
10251 if (ShouldConvertToFastElements()) { 10251 if (self->ShouldConvertToFastElements()) {
10252 uint32_t new_length = 0; 10252 uint32_t new_length = 0;
10253 if (IsJSArray()) { 10253 if (self->IsJSArray()) {
10254 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 10254 CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length));
10255 } else { 10255 } else {
10256 new_length = dictionary->max_number_key() + 1; 10256 new_length = dictionary->max_number_key() + 1;
10257 } 10257 }
10258 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays 10258 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays
10259 ? kAllowSmiElements 10259 ? kAllowSmiElements
10260 : kDontAllowSmiElements; 10260 : kDontAllowSmiElements;
10261 bool has_smi_only_elements = false; 10261 bool has_smi_only_elements = false;
10262 bool should_convert_to_fast_double_elements = 10262 bool should_convert_to_fast_double_elements =
10263 ShouldConvertToFastDoubleElements(&has_smi_only_elements); 10263 self->ShouldConvertToFastDoubleElements(&has_smi_only_elements);
10264 if (has_smi_only_elements) { 10264 if (has_smi_only_elements) {
10265 smi_mode = kForceSmiElements; 10265 smi_mode = kForceSmiElements;
10266 } 10266 }
10267 MaybeObject* result = should_convert_to_fast_double_elements 10267 MaybeObject* result = should_convert_to_fast_double_elements
10268 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) 10268 ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length)
10269 : SetFastElementsCapacityAndLength(new_length, 10269 : self->SetFastElementsCapacityAndLength(
10270 new_length, 10270 new_length, new_length, smi_mode);
10271 smi_mode); 10271 self->ValidateElements();
10272 ValidateElements();
10273 if (result->IsFailure()) return result; 10272 if (result->IsFailure()) return result;
10274 #ifdef DEBUG 10273 #ifdef DEBUG
10275 if (FLAG_trace_normalization) { 10274 if (FLAG_trace_normalization) {
10276 PrintF("Object elements are fast case again:\n"); 10275 PrintF("Object elements are fast case again:\n");
10277 Print(); 10276 Print();
10278 } 10277 }
10279 #endif 10278 #endif
10280 } 10279 }
10281 return value; 10280 return *value;
10282 } 10281 }
10283 10282
10284 10283
10285 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( 10284 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement(
10286 uint32_t index, 10285 uint32_t index,
10287 Object* value, 10286 Object* value,
10288 StrictModeFlag strict_mode, 10287 StrictModeFlag strict_mode,
10289 bool check_prototype) { 10288 bool check_prototype) {
10290 ASSERT(HasFastDoubleElements()); 10289 ASSERT(HasFastDoubleElements());
10291 10290
(...skipping 3740 matching lines...) Expand 10 before | Expand all | Expand 10 after
14032 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); 14031 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER);
14033 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); 14032 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER);
14034 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); 14033 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER);
14035 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); 14034 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER);
14036 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); 14035 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER);
14037 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); 14036 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER);
14038 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); 14037 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER);
14039 } 14038 }
14040 14039
14041 } } // namespace v8::internal 14040 } } // 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