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

Side by Side Diff: src/objects.cc

Issue 35413006: Correct handling of arrays with callbacks in the prototype chain. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE (actually small fix to previous rebase) Created 7 years, 2 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
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 2930 matching lines...) Expand 10 before | Expand all | Expand 10 after
2941 bool has_pending_exception; 2941 bool has_pending_exception;
2942 Handle<Object> argv[] = { value }; 2942 Handle<Object> argv[] = { value };
2943 Execution::Call( 2943 Execution::Call(
2944 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); 2944 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception);
2945 // Check for pending exception and return the result. 2945 // Check for pending exception and return the result.
2946 if (has_pending_exception) return Handle<Object>(); 2946 if (has_pending_exception) return Handle<Object>();
2947 return value; 2947 return value;
2948 } 2948 }
2949 2949
2950 2950
2951 bool JSReceiver::MayHaveIndexedCallbacksInPrototypeChain() {
2952 Heap* heap = GetHeap();
2953 for (Object* pt = GetPrototype();
2954 pt != heap->null_value();
2955 pt = pt->GetPrototype(GetIsolate())) {
2956 if (pt->IsJSProxy()) {
2957 // Be conservative, don't walk into proxies.
2958 return true;
2959 }
2960
2961 if (JSObject::cast(pt)->map()->has_element_callbacks()) {
2962 return true;
2963 }
2964 }
2965
2966 return false;
2967 }
2968
2969
2951 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 2970 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
2952 uint32_t index, 2971 uint32_t index,
2953 Object* value, 2972 Object* value,
2954 bool* found, 2973 bool* found,
2955 StrictModeFlag strict_mode) { 2974 StrictModeFlag strict_mode) {
2956 Heap* heap = GetHeap(); 2975 Heap* heap = GetHeap();
2957 for (Object* pt = GetPrototype(); 2976 for (Object* pt = GetPrototype();
2958 pt != heap->null_value(); 2977 pt != heap->null_value();
2959 pt = pt->GetPrototype(GetIsolate())) { 2978 pt = pt->GetPrototype(GetIsolate())) {
2960 if (pt->IsJSProxy()) { 2979 if (pt->IsJSProxy()) {
(...skipping 3261 matching lines...) Expand 10 before | Expand all | Expand 10 after
6222 } 6241 }
6223 return true; 6242 return true;
6224 } 6243 }
6225 6244
6226 6245
6227 void JSObject::SetElementCallback(Handle<JSObject> object, 6246 void JSObject::SetElementCallback(Handle<JSObject> object,
6228 uint32_t index, 6247 uint32_t index,
6229 Handle<Object> structure, 6248 Handle<Object> structure,
6230 PropertyAttributes attributes) { 6249 PropertyAttributes attributes) {
6231 Heap* heap = object->GetHeap(); 6250 Heap* heap = object->GetHeap();
6251 Handle<Map> old_map(object->map());
6232 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6252 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6233 6253
6234 // Normalize elements to make this operation simple. 6254 // Normalize elements to make this operation simple.
6235 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6255 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6236 ASSERT(object->HasDictionaryElements() || 6256 ASSERT(object->HasDictionaryElements() ||
6237 object->HasDictionaryArgumentsElements()); 6257 object->HasDictionaryArgumentsElements());
6258 bool map_changed = object->map() != *old_map;
6238 6259
6239 // Update the dictionary with the new CALLBACKS property. 6260 // Update the dictionary with the new CALLBACKS property.
6240 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6261 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6241 details); 6262 details);
6242 dictionary->set_requires_slow_elements(); 6263 dictionary->set_requires_slow_elements();
6243 6264
6244 // Update the dictionary backing store on the object. 6265 // Update the dictionary backing store on the object.
6245 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { 6266 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
6246 // Also delete any parameter alias. 6267 // Also delete any parameter alias.
6247 // 6268 //
6248 // TODO(kmillikin): when deleting the last parameter alias we could 6269 // TODO(kmillikin): when deleting the last parameter alias we could
6249 // switch to a direct backing store without the parameter map. This 6270 // switch to a direct backing store without the parameter map. This
6250 // would allow GC of the context. 6271 // would allow GC of the context.
6251 FixedArray* parameter_map = FixedArray::cast(object->elements()); 6272 FixedArray* parameter_map = FixedArray::cast(object->elements());
6252 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { 6273 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
6253 parameter_map->set(index + 2, heap->the_hole_value()); 6274 parameter_map->set(index + 2, heap->the_hole_value());
6254 } 6275 }
6255 parameter_map->set(1, *dictionary); 6276 parameter_map->set(1, *dictionary);
6256 } else { 6277 } else {
6257 object->set_elements(*dictionary); 6278 object->set_elements(*dictionary);
6258 } 6279 }
6280
6281 if (!object->map()->has_element_callbacks()) {
6282 if (!map_changed) {
6283 Handle<Map> new_map = Map::Copy(handle(object->map()));
6284 object->set_map(*new_map);
6285 }
6286 object->map()->set_has_element_callbacks(true);
6287 }
6288
6289 // If we are the array prototype object, rebuild the cache.
6290 Isolate* isolate = object->GetIsolate();
6291 if (isolate->initial_array_prototype().is_identical_to(object)) {
6292 // Install the initial map, new_ek_map in the function prototype for
6293 // array.
6294 Handle<JSFunction> array_function(
6295 isolate->global_context()->array_function(), isolate);
6296 JSFunction::SetPrototype(array_function, object);
6297 } else if (isolate->initial_object_prototype().is_identical_to(object)) {
6298 Handle<JSFunction> object_function(
6299 isolate->global_context()->object_function(), isolate);
6300 JSFunction::SetPrototype(object_function, object);
6301 }
6302
6303 // TODO(mvstanton): With a dependency group we can avoid the need to
6304 // deoptimize code that doesn't depend on the changed maps. Address this
6305 // in a follow-up checkin.
6306 Deoptimizer::DeoptimizeAll(object->GetIsolate());
6307 object->GetHeap()->ClearAllKeyedStoreICs();
6259 } 6308 }
6260 6309
6261 6310
6262 void JSObject::SetPropertyCallback(Handle<JSObject> object, 6311 void JSObject::SetPropertyCallback(Handle<JSObject> object,
6263 Handle<Name> name, 6312 Handle<Name> name,
6264 Handle<Object> structure, 6313 Handle<Object> structure,
6265 PropertyAttributes attributes) { 6314 PropertyAttributes attributes) {
6266 // Normalize object to make this operation simple. 6315 // Normalize object to make this operation simple.
6267 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 6316 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
6268 6317
(...skipping 4301 matching lines...) Expand 10 before | Expand all | Expand 10 after
10570 if (--n == 0) { 10619 if (--n == 0) {
10571 info->set_target_cell(replace_with); 10620 info->set_target_cell(replace_with);
10572 return; 10621 return;
10573 } 10622 }
10574 } 10623 }
10575 UNREACHABLE(); 10624 UNREACHABLE();
10576 } 10625 }
10577 10626
10578 10627
10579 void Code::ClearInlineCaches() { 10628 void Code::ClearInlineCaches() {
10629 ClearInlineCaches(NULL);
10630 }
10631
10632
10633 void Code::ClearInlineCaches(Code::Kind kind) {
10634 ClearInlineCaches(&kind);
10635 }
10636
10637
10638 void Code::ClearInlineCaches(Code::Kind* kind) {
10580 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 10639 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
10581 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | 10640 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
10582 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | 10641 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) |
10583 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); 10642 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT);
10584 for (RelocIterator it(this, mask); !it.done(); it.next()) { 10643 for (RelocIterator it(this, mask); !it.done(); it.next()) {
10585 RelocInfo* info = it.rinfo(); 10644 RelocInfo* info = it.rinfo();
10586 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); 10645 Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
10587 if (target->is_inline_cache_stub()) { 10646 if (target->is_inline_cache_stub()) {
10588 IC::Clear(this->GetIsolate(), info->pc()); 10647 if (kind == NULL || *kind == target->kind()) {
10648 IC::Clear(this->GetIsolate(), info->pc());
10649 }
10589 } 10650 }
10590 } 10651 }
10591 } 10652 }
10592 10653
10593 10654
10594 void Code::ClearTypeFeedbackCells(Heap* heap) { 10655 void Code::ClearTypeFeedbackCells(Heap* heap) {
10595 if (kind() != FUNCTION) return; 10656 if (kind() != FUNCTION) return;
10596 Object* raw_info = type_feedback_info(); 10657 Object* raw_info = type_feedback_info();
10597 if (raw_info->IsTypeFeedbackInfo()) { 10658 if (raw_info->IsTypeFeedbackInfo()) {
10598 TypeFeedbackCells* type_feedback_cells = 10659 TypeFeedbackCells* type_feedback_cells =
(...skipping 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after
12748 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 12809 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12749 ASSERT(!map()->is_observed()); 12810 ASSERT(!map()->is_observed());
12750 ElementsKind from_kind = map()->elements_kind(); 12811 ElementsKind from_kind = map()->elements_kind();
12751 12812
12752 if (IsFastHoleyElementsKind(from_kind)) { 12813 if (IsFastHoleyElementsKind(from_kind)) {
12753 to_kind = GetHoleyElementsKind(to_kind); 12814 to_kind = GetHoleyElementsKind(to_kind);
12754 } 12815 }
12755 12816
12756 if (from_kind == to_kind) return this; 12817 if (from_kind == to_kind) return this;
12757 12818
12758 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12819 // Don't update the site if to_kind isn't fast
12759 if (maybe_failure->IsFailure()) return maybe_failure; 12820 if (IsFastElementsKind(to_kind)) {
12821 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
12822 if (maybe_failure->IsFailure()) return maybe_failure;
12823 }
12760 12824
12761 Isolate* isolate = GetIsolate(); 12825 Isolate* isolate = GetIsolate();
12762 if (elements() == isolate->heap()->empty_fixed_array() || 12826 if (elements() == isolate->heap()->empty_fixed_array() ||
12763 (IsFastSmiOrObjectElementsKind(from_kind) && 12827 (IsFastSmiOrObjectElementsKind(from_kind) &&
12764 IsFastSmiOrObjectElementsKind(to_kind)) || 12828 IsFastSmiOrObjectElementsKind(to_kind)) ||
12765 (from_kind == FAST_DOUBLE_ELEMENTS && 12829 (from_kind == FAST_DOUBLE_ELEMENTS &&
12766 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { 12830 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
12767 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); 12831 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND);
12768 // No change is needed to the elements() buffer, the transition 12832 // No change is needed to the elements() buffer, the transition
12769 // only requires a map change. 12833 // only requires a map change.
(...skipping 3616 matching lines...) Expand 10 before | Expand all | Expand 10 after
16386 #define ERROR_MESSAGES_TEXTS(C, T) T, 16450 #define ERROR_MESSAGES_TEXTS(C, T) T,
16387 static const char* error_messages_[] = { 16451 static const char* error_messages_[] = {
16388 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16452 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16389 }; 16453 };
16390 #undef ERROR_MESSAGES_TEXTS 16454 #undef ERROR_MESSAGES_TEXTS
16391 return error_messages_[reason]; 16455 return error_messages_[reason];
16392 } 16456 }
16393 16457
16394 16458
16395 } } // namespace v8::internal 16459 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | test/mjsunit/getters-on-elements.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698