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

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: A few test updates and simpler prototype updating. 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
« src/ic.cc ('K') | « src/objects.h ('k') | src/objects-inl.h » ('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 2905 matching lines...) Expand 10 before | Expand all | Expand 10 after
2916 bool has_pending_exception; 2916 bool has_pending_exception;
2917 Handle<Object> argv[] = { value }; 2917 Handle<Object> argv[] = { value };
2918 Execution::Call( 2918 Execution::Call(
2919 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); 2919 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception);
2920 // Check for pending exception and return the result. 2920 // Check for pending exception and return the result.
2921 if (has_pending_exception) return Handle<Object>(); 2921 if (has_pending_exception) return Handle<Object>();
2922 return value; 2922 return value;
2923 } 2923 }
2924 2924
2925 2925
2926 bool JSReceiver::MayHaveIndexedCallbacksInPrototypeChain() {
2927 Heap* heap = GetHeap();
2928 for (Object* pt = GetPrototype();
2929 pt != heap->null_value();
2930 pt = pt->GetPrototype(GetIsolate())) {
2931 if (pt->IsJSProxy()) {
2932 // Be conservative, don't walk into proxies.
2933 return true;
2934 }
2935
2936 if (JSObject::cast(pt)->map()->has_element_callbacks()) {
2937 return true;
2938 }
2939 }
2940
2941 return false;
2942 }
2943
2944
2926 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 2945 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
2927 uint32_t index, 2946 uint32_t index,
2928 Object* value, 2947 Object* value,
2929 bool* found, 2948 bool* found,
2930 StrictModeFlag strict_mode) { 2949 StrictModeFlag strict_mode) {
2931 Heap* heap = GetHeap(); 2950 Heap* heap = GetHeap();
2932 for (Object* pt = GetPrototype(); 2951 for (Object* pt = GetPrototype();
2933 pt != heap->null_value(); 2952 pt != heap->null_value();
2934 pt = pt->GetPrototype(GetIsolate())) { 2953 pt = pt->GetPrototype(GetIsolate())) {
2935 if (pt->IsJSProxy()) { 2954 if (pt->IsJSProxy()) {
(...skipping 3261 matching lines...) Expand 10 before | Expand all | Expand 10 after
6197 } 6216 }
6198 return true; 6217 return true;
6199 } 6218 }
6200 6219
6201 6220
6202 void JSObject::SetElementCallback(Handle<JSObject> object, 6221 void JSObject::SetElementCallback(Handle<JSObject> object,
6203 uint32_t index, 6222 uint32_t index,
6204 Handle<Object> structure, 6223 Handle<Object> structure,
6205 PropertyAttributes attributes) { 6224 PropertyAttributes attributes) {
6206 Heap* heap = object->GetHeap(); 6225 Heap* heap = object->GetHeap();
6226 Handle<Map> old_map(object->map());
6207 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6227 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6208 6228
6209 // Normalize elements to make this operation simple. 6229 // Normalize elements to make this operation simple.
6210 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); 6230 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6211 ASSERT(object->HasDictionaryElements() || 6231 ASSERT(object->HasDictionaryElements() ||
6212 object->HasDictionaryArgumentsElements()); 6232 object->HasDictionaryArgumentsElements());
6233 bool map_changed = object->map() != *old_map;
6213 6234
6214 // Update the dictionary with the new CALLBACKS property. 6235 // Update the dictionary with the new CALLBACKS property.
6215 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, 6236 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6216 details); 6237 details);
6217 dictionary->set_requires_slow_elements(); 6238 dictionary->set_requires_slow_elements();
6218 6239
6219 // Update the dictionary backing store on the object. 6240 // Update the dictionary backing store on the object.
6220 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { 6241 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
6221 // Also delete any parameter alias. 6242 // Also delete any parameter alias.
6222 // 6243 //
6223 // TODO(kmillikin): when deleting the last parameter alias we could 6244 // TODO(kmillikin): when deleting the last parameter alias we could
6224 // switch to a direct backing store without the parameter map. This 6245 // switch to a direct backing store without the parameter map. This
6225 // would allow GC of the context. 6246 // would allow GC of the context.
6226 FixedArray* parameter_map = FixedArray::cast(object->elements()); 6247 FixedArray* parameter_map = FixedArray::cast(object->elements());
6227 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { 6248 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
6228 parameter_map->set(index + 2, heap->the_hole_value()); 6249 parameter_map->set(index + 2, heap->the_hole_value());
6229 } 6250 }
6230 parameter_map->set(1, *dictionary); 6251 parameter_map->set(1, *dictionary);
6231 } else { 6252 } else {
6232 object->set_elements(*dictionary); 6253 object->set_elements(*dictionary);
6233 } 6254 }
6255
6256 if (!object->map()->has_element_callbacks()) {
6257 if (!map_changed) {
6258 Handle<Map> new_map = Map::Copy(handle(object->map()));
6259 object->set_map(*new_map);
6260 }
6261 object->map()->set_has_element_callbacks(true);
danno 2013/10/23 12:22:11 This isn't quite right. You might "pollute" normal
6262 }
6263
6264 // If we are the array prototype object, rebuild the cache.
6265 Isolate* isolate = object->GetIsolate();
6266 if (isolate->initial_array_prototype().is_identical_to(object)) {
6267 // Install the initial map, new_ek_map in the function prototype for
danno 2013/10/23 12:22:11 Is this comment correct?
6268 // array.
6269 Handle<JSFunction> array_function(
6270 isolate->global_context()->array_function(), isolate);
6271 JSFunction::SetPrototype(array_function, object);
danno 2013/10/23 12:22:11 You are "rebuilding the cache" by side effect, whi
6272 } else if (isolate->initial_object_prototype().is_identical_to(object)) {
6273 Handle<JSFunction> object_function(
6274 isolate->global_context()->object_function(), isolate);
6275 JSFunction::SetPrototype(object_function, object);
6276 }
6277
6278 // TODO(mvstanton): With a dependency group we can avoid the need to
6279 // deoptimize code that doesn't depend on the changed maps. Address this
6280 // in a follow-up checkin.
6281 Deoptimizer::DeoptimizeAll(object->GetIsolate());
danno 2013/10/23 12:22:11 Oh, *the humanity* Are you sure it can't be in thi
6282 object->GetHeap()->ClearAllKeyedStoreICs();
6234 } 6283 }
6235 6284
6236 6285
6237 void JSObject::SetPropertyCallback(Handle<JSObject> object, 6286 void JSObject::SetPropertyCallback(Handle<JSObject> object,
6238 Handle<Name> name, 6287 Handle<Name> name,
6239 Handle<Object> structure, 6288 Handle<Object> structure,
6240 PropertyAttributes attributes) { 6289 PropertyAttributes attributes) {
6241 // Normalize object to make this operation simple. 6290 // Normalize object to make this operation simple.
6242 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); 6291 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
6243 6292
(...skipping 4309 matching lines...) Expand 10 before | Expand all | Expand 10 after
10553 if (--n == 0) { 10602 if (--n == 0) {
10554 info->set_target_cell(replace_with); 10603 info->set_target_cell(replace_with);
10555 return; 10604 return;
10556 } 10605 }
10557 } 10606 }
10558 UNREACHABLE(); 10607 UNREACHABLE();
10559 } 10608 }
10560 10609
10561 10610
10562 void Code::ClearInlineCaches() { 10611 void Code::ClearInlineCaches() {
10612 ClearInlineCaches(NULL);
10613 }
10614
10615
10616 void Code::ClearInlineCaches(Code::Kind kind) {
10617 ClearInlineCaches(&kind);
10618 }
10619
10620
10621 void Code::ClearInlineCaches(Code::Kind* kind) {
10563 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | 10622 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
10564 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) | 10623 RelocInfo::ModeMask(RelocInfo::CONSTRUCT_CALL) |
10565 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) | 10624 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID) |
10566 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT); 10625 RelocInfo::ModeMask(RelocInfo::CODE_TARGET_CONTEXT);
10567 for (RelocIterator it(this, mask); !it.done(); it.next()) { 10626 for (RelocIterator it(this, mask); !it.done(); it.next()) {
10568 RelocInfo* info = it.rinfo(); 10627 RelocInfo* info = it.rinfo();
10569 Code* target(Code::GetCodeFromTargetAddress(info->target_address())); 10628 Code* target(Code::GetCodeFromTargetAddress(info->target_address()));
10570 if (target->is_inline_cache_stub()) { 10629 if (target->is_inline_cache_stub()) {
10571 IC::Clear(this->GetIsolate(), info->pc()); 10630 if (kind == NULL || *kind == target->kind()) {
10631 IC::Clear(this->GetIsolate(), info->pc());
10632 }
10572 } 10633 }
10573 } 10634 }
10574 } 10635 }
10575 10636
10576 10637
10577 void Code::ClearTypeFeedbackCells(Heap* heap) { 10638 void Code::ClearTypeFeedbackCells(Heap* heap) {
10578 if (kind() != FUNCTION) return; 10639 if (kind() != FUNCTION) return;
10579 Object* raw_info = type_feedback_info(); 10640 Object* raw_info = type_feedback_info();
10580 if (raw_info->IsTypeFeedbackInfo()) { 10641 if (raw_info->IsTypeFeedbackInfo()) {
10581 TypeFeedbackCells* type_feedback_cells = 10642 TypeFeedbackCells* type_feedback_cells =
(...skipping 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after
12731 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { 12792 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12732 ASSERT(!map()->is_observed()); 12793 ASSERT(!map()->is_observed());
12733 ElementsKind from_kind = map()->elements_kind(); 12794 ElementsKind from_kind = map()->elements_kind();
12734 12795
12735 if (IsFastHoleyElementsKind(from_kind)) { 12796 if (IsFastHoleyElementsKind(from_kind)) {
12736 to_kind = GetHoleyElementsKind(to_kind); 12797 to_kind = GetHoleyElementsKind(to_kind);
12737 } 12798 }
12738 12799
12739 if (from_kind == to_kind) return this; 12800 if (from_kind == to_kind) return this;
12740 12801
12741 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12802 // Don't update the site if to_kind isn't fast
12742 if (maybe_failure->IsFailure()) return maybe_failure; 12803 if (IsFastElementsKind(to_kind)) {
12804 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind);
12805 if (maybe_failure->IsFailure()) return maybe_failure;
12806 }
12743 12807
12744 Isolate* isolate = GetIsolate(); 12808 Isolate* isolate = GetIsolate();
12745 if (elements() == isolate->heap()->empty_fixed_array() || 12809 if (elements() == isolate->heap()->empty_fixed_array() ||
12746 (IsFastSmiOrObjectElementsKind(from_kind) && 12810 (IsFastSmiOrObjectElementsKind(from_kind) &&
12747 IsFastSmiOrObjectElementsKind(to_kind)) || 12811 IsFastSmiOrObjectElementsKind(to_kind)) ||
12748 (from_kind == FAST_DOUBLE_ELEMENTS && 12812 (from_kind == FAST_DOUBLE_ELEMENTS &&
12749 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { 12813 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
12750 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); 12814 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND);
12751 // No change is needed to the elements() buffer, the transition 12815 // No change is needed to the elements() buffer, the transition
12752 // only requires a map change. 12816 // only requires a map change.
(...skipping 3621 matching lines...) Expand 10 before | Expand all | Expand 10 after
16374 #define ERROR_MESSAGES_TEXTS(C, T) T, 16438 #define ERROR_MESSAGES_TEXTS(C, T) T,
16375 static const char* error_messages_[] = { 16439 static const char* error_messages_[] = {
16376 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16440 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16377 }; 16441 };
16378 #undef ERROR_MESSAGES_TEXTS 16442 #undef ERROR_MESSAGES_TEXTS
16379 return error_messages_[reason]; 16443 return error_messages_[reason];
16380 } 16444 }
16381 16445
16382 16446
16383 } } // namespace v8::internal 16447 } } // namespace v8::internal
OLDNEW
« src/ic.cc ('K') | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698