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

Side by Side Diff: src/objects.cc

Issue 494153002: Avoid one repeated property lookup when computing store ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments (triggering a bug in doing so) Created 6 years, 4 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/objects.h ('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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h" 8 #include "src/allocation-site-scopes.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 return fun->IsJSFunction() || 101 return fun->IsJSFunction() ||
102 (fun->IsHeapObject() && 102 (fun->IsHeapObject() &&
103 HeapObject::cast(fun)->map()->has_instance_call_handler()); 103 HeapObject::cast(fun)->map()->has_instance_call_handler());
104 } 104 }
105 105
106 106
107 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { 107 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) {
108 for (; it->IsFound(); it->Next()) { 108 for (; it->IsFound(); it->Next()) {
109 switch (it->state()) { 109 switch (it->state()) {
110 case LookupIterator::NOT_FOUND: 110 case LookupIterator::NOT_FOUND:
111 case LookupIterator::TRANSITION:
111 UNREACHABLE(); 112 UNREACHABLE();
112 case LookupIterator::JSPROXY: 113 case LookupIterator::JSPROXY:
113 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(), 114 return JSProxy::GetPropertyWithHandler(it->GetHolder<JSProxy>(),
114 it->GetReceiver(), it->name()); 115 it->GetReceiver(), it->name());
115 case LookupIterator::INTERCEPTOR: { 116 case LookupIterator::INTERCEPTOR: {
116 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor( 117 MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithInterceptor(
117 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); 118 it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
118 if (!maybe_result.is_null()) return maybe_result; 119 if (!maybe_result.is_null()) return maybe_result;
119 if (it->isolate()->has_pending_exception()) return maybe_result; 120 if (it->isolate()->has_pending_exception()) return maybe_result;
120 break; 121 break;
(...skipping 22 matching lines...) Expand all
143 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, 144 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object,
144 Handle<Name> key) { 145 Handle<Name> key) {
145 LookupIterator it(object, key, LookupIterator::CHECK_DERIVED_PROPERTY); 146 LookupIterator it(object, key, LookupIterator::CHECK_DERIVED_PROPERTY);
146 return GetDataProperty(&it); 147 return GetDataProperty(&it);
147 } 148 }
148 149
149 150
150 Handle<Object> JSObject::GetDataProperty(LookupIterator* it) { 151 Handle<Object> JSObject::GetDataProperty(LookupIterator* it) {
151 for (; it->IsFound(); it->Next()) { 152 for (; it->IsFound(); it->Next()) {
152 switch (it->state()) { 153 switch (it->state()) {
153 case LookupIterator::NOT_FOUND:
154 case LookupIterator::ACCESS_CHECK: 154 case LookupIterator::ACCESS_CHECK:
155 case LookupIterator::INTERCEPTOR: 155 case LookupIterator::INTERCEPTOR:
156 case LookupIterator::NOT_FOUND:
157 case LookupIterator::TRANSITION:
156 UNREACHABLE(); 158 UNREACHABLE();
157 case LookupIterator::JSPROXY: 159 case LookupIterator::JSPROXY:
158 it->NotFound(); 160 it->NotFound();
159 return it->isolate()->factory()->undefined_value(); 161 return it->isolate()->factory()->undefined_value();
160 case LookupIterator::PROPERTY: 162 case LookupIterator::PROPERTY:
161 if (!it->HasProperty()) continue; 163 if (!it->HasProperty()) continue;
162 switch (it->property_kind()) { 164 switch (it->property_kind()) {
163 case LookupIterator::DATA: 165 case LookupIterator::DATA:
164 return it->GetDataValue(); 166 return it->GetDataValue();
165 case LookupIterator::ACCESSOR: 167 case LookupIterator::ACCESSOR:
(...skipping 2541 matching lines...) Expand 10 before | Expand all | Expand 10 after
2707 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) { 2709 if (proto_map->is_deprecated() && JSObject::TryMigrateInstance(holder)) {
2708 proto_map = Handle<Map>(holder->map()); 2710 proto_map = Handle<Map>(holder->map());
2709 } 2711 }
2710 } 2712 }
2711 return TryUpdateInternal(map); 2713 return TryUpdateInternal(map);
2712 } 2714 }
2713 2715
2714 2716
2715 // static 2717 // static
2716 Handle<Map> Map::Update(Handle<Map> map) { 2718 Handle<Map> Map::Update(Handle<Map> map) {
2719 if (!map->is_deprecated()) return map;
2717 return GeneralizeRepresentation(map, 0, Representation::None(), 2720 return GeneralizeRepresentation(map, 0, Representation::None(),
2718 HeapType::None(map->GetIsolate()), 2721 HeapType::None(map->GetIsolate()),
2719 ALLOW_AS_CONSTANT); 2722 ALLOW_AS_CONSTANT);
2720 } 2723 }
2721 2724
2722 2725
2723 // static 2726 // static
2724 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) { 2727 MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) {
2725 DisallowHeapAllocation no_allocation; 2728 DisallowHeapAllocation no_allocation;
2726 DisallowDeoptimization no_deoptimization(old_map->GetIsolate()); 2729 DisallowDeoptimization no_deoptimization(old_map->GetIsolate());
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
2887 it->GetAccessors(), strict_mode); 2890 it->GetAccessors(), strict_mode);
2888 } 2891 }
2889 break; 2892 break;
2890 case LookupIterator::DATA: 2893 case LookupIterator::DATA:
2891 if (it->HolderIsReceiverOrHiddenPrototype()) { 2894 if (it->HolderIsReceiverOrHiddenPrototype()) {
2892 return SetDataProperty(it, value); 2895 return SetDataProperty(it, value);
2893 } 2896 }
2894 } 2897 }
2895 done = true; 2898 done = true;
2896 break; 2899 break;
2900
2901 case LookupIterator::TRANSITION:
2902 done = true;
2903 break;
2897 } 2904 }
2898 2905
2899 if (done) break; 2906 if (done) break;
2900 } 2907 }
2901 2908
2902 return AddDataProperty(it, value, NONE, strict_mode, store_mode); 2909 return AddDataProperty(it, value, NONE, strict_mode, store_mode);
2903 } 2910 }
2904 2911
2905 2912
2906 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it, 2913 MaybeHandle<Object> Object::WriteToReadOnlyProperty(LookupIterator* it,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2953 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, 2960 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it,
2954 Handle<Object> value, 2961 Handle<Object> value,
2955 PropertyAttributes attributes, 2962 PropertyAttributes attributes,
2956 StrictMode strict_mode, 2963 StrictMode strict_mode,
2957 StoreFromKeyed store_mode) { 2964 StoreFromKeyed store_mode) {
2958 DCHECK(!it->GetReceiver()->IsJSProxy()); 2965 DCHECK(!it->GetReceiver()->IsJSProxy());
2959 if (!it->GetReceiver()->IsJSObject()) { 2966 if (!it->GetReceiver()->IsJSObject()) {
2960 // TODO(verwaest): Throw a TypeError with a more specific message. 2967 // TODO(verwaest): Throw a TypeError with a more specific message.
2961 return WriteToReadOnlyProperty(it, value, strict_mode); 2968 return WriteToReadOnlyProperty(it, value, strict_mode);
2962 } 2969 }
2963 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); 2970 Handle<JSObject> receiver = it->GetStoreTarget();
2964 2971
2965 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) 2972 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject)
2966 // instead. If the prototype is Null, the proxy is detached. 2973 // instead. If the prototype is Null, the proxy is detached.
2967 if (receiver->IsJSGlobalProxy()) { 2974 if (receiver->IsJSGlobalProxy()) return value;
2968 // Trying to assign to a detached proxy.
2969 PrototypeIterator iter(it->isolate(), receiver);
2970 if (iter.IsAtEnd()) return value;
2971 receiver =
2972 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
2973 }
2974 2975
2975 if (!it->name().is_identical_to(it->isolate()->factory()->hidden_string()) && 2976 // Possibly migrate to the most up-to-date map that will be able to store
2976 !receiver->map()->is_extensible()) { 2977 // |value| under it->name() with |attributes|.
2978 it->PrepareTransitionToDataProperty(value, attributes, store_mode);
2979 if (it->state() != LookupIterator::TRANSITION) {
2977 if (strict_mode == SLOPPY) return value; 2980 if (strict_mode == SLOPPY) return value;
2978 2981
2979 Handle<Object> args[1] = {it->name()}; 2982 Handle<Object> args[1] = {it->name()};
2980 Handle<Object> error = it->factory()->NewTypeError( 2983 Handle<Object> error = it->factory()->NewTypeError(
2981 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); 2984 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args)));
2982 return it->isolate()->Throw<Object>(error); 2985 return it->isolate()->Throw<Object>(error);
2983 } 2986 }
2984 2987 it->ApplyTransitionToDataProperty();
2985 // Possibly migrate to the most up-to-date map that will be able to store
2986 // |value| under it->name() with |attributes|.
2987 it->TransitionToDataProperty(value, attributes, store_mode);
2988 2988
2989 // TODO(verwaest): Encapsulate dictionary handling better. 2989 // TODO(verwaest): Encapsulate dictionary handling better.
2990 if (receiver->map()->is_dictionary_map()) { 2990 if (receiver->map()->is_dictionary_map()) {
2991 // TODO(verwaest): Probably should ensure this is done beforehand. 2991 // TODO(verwaest): Probably should ensure this is done beforehand.
2992 it->InternalizeName(); 2992 it->InternalizeName();
2993 JSObject::AddSlowProperty(receiver, it->name(), value, attributes); 2993 JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
2994 } else { 2994 } else {
2995 // Write the property value. 2995 // Write the property value.
2996 it->WriteDataValue(value); 2996 it->WriteDataValue(value);
2997 } 2997 }
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
3372 } 3372 }
3373 3373
3374 3374
3375 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object, 3375 Handle<Map> JSObject::GetElementsTransitionMap(Handle<JSObject> object,
3376 ElementsKind to_kind) { 3376 ElementsKind to_kind) {
3377 Handle<Map> map(object->map()); 3377 Handle<Map> map(object->map());
3378 return Map::TransitionElementsTo(map, to_kind); 3378 return Map::TransitionElementsTo(map, to_kind);
3379 } 3379 }
3380 3380
3381 3381
3382 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name,
3383 LookupResult* result) {
3384 DisallowHeapAllocation no_gc;
3385 if (IsJSGlobalProxy()) {
3386 PrototypeIterator iter(GetIsolate(), this);
3387 if (iter.IsAtEnd()) return result->NotFound();
3388 DCHECK(iter.GetCurrent()->IsJSGlobalObject());
3389 return JSObject::cast(iter.GetCurrent())
3390 ->LookupOwnRealNamedProperty(name, result);
3391 }
3392
3393 if (HasFastProperties()) {
3394 map()->LookupDescriptor(this, *name, result);
3395 // A property or a map transition was found. We return all of these result
3396 // types because LookupOwnRealNamedProperty is used when setting
3397 // properties where map transitions are handled.
3398 DCHECK(!result->IsFound() ||
3399 (result->holder() == this && result->IsFastPropertyType()));
3400 return;
3401 }
3402
3403 int entry = property_dictionary()->FindEntry(name);
3404 if (entry != NameDictionary::kNotFound) {
3405 Object* value = property_dictionary()->ValueAt(entry);
3406 if (IsGlobalObject()) {
3407 PropertyDetails d = property_dictionary()->DetailsAt(entry);
3408 if (d.IsDeleted() || PropertyCell::cast(value)->value()->IsTheHole()) {
3409 result->NotFound();
3410 return;
3411 }
3412 value = PropertyCell::cast(value)->value();
3413 }
3414 result->DictionaryResult(this, entry);
3415 return;
3416 }
3417
3418 result->NotFound();
3419 }
3420
3421
3422 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, 3382 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy,
3423 Handle<Name> name) { 3383 Handle<Name> name) {
3424 Isolate* isolate = proxy->GetIsolate(); 3384 Isolate* isolate = proxy->GetIsolate();
3425 3385
3426 // TODO(rossberg): adjust once there is a story for symbols vs proxies. 3386 // TODO(rossberg): adjust once there is a story for symbols vs proxies.
3427 if (name->IsSymbol()) return maybe(false); 3387 if (name->IsSymbol()) return maybe(false);
3428 3388
3429 Handle<Object> args[] = { name }; 3389 Handle<Object> args[] = { name };
3430 Handle<Object> result; 3390 Handle<Object> result;
3431 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 3391 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
3840 Handle<Object> value, 3800 Handle<Object> value,
3841 PropertyAttributes attributes, 3801 PropertyAttributes attributes,
3842 ExecutableAccessorInfoHandling handling) { 3802 ExecutableAccessorInfoHandling handling) {
3843 DCHECK(!value->IsTheHole()); 3803 DCHECK(!value->IsTheHole());
3844 LookupIterator it(object, name, 3804 LookupIterator it(object, name,
3845 LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR); 3805 LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR);
3846 bool is_observed = object->map()->is_observed() && 3806 bool is_observed = object->map()->is_observed() &&
3847 *name != it.isolate()->heap()->hidden_string(); 3807 *name != it.isolate()->heap()->hidden_string();
3848 for (; it.IsFound(); it.Next()) { 3808 for (; it.IsFound(); it.Next()) {
3849 switch (it.state()) { 3809 switch (it.state()) {
3810 case LookupIterator::INTERCEPTOR:
3811 case LookupIterator::JSPROXY:
3850 case LookupIterator::NOT_FOUND: 3812 case LookupIterator::NOT_FOUND:
3851 case LookupIterator::JSPROXY: 3813 case LookupIterator::TRANSITION:
3852 case LookupIterator::INTERCEPTOR:
3853 UNREACHABLE(); 3814 UNREACHABLE();
3854 3815
3855 case LookupIterator::ACCESS_CHECK: 3816 case LookupIterator::ACCESS_CHECK:
3856 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) { 3817 if (!it.isolate()->MayNamedAccess(object, name, v8::ACCESS_SET)) {
3857 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); 3818 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY);
3858 } 3819 }
3859 break; 3820 break;
3860 3821
3861 case LookupIterator::PROPERTY: { 3822 case LookupIterator::PROPERTY: {
3862 if (!it.HasProperty()) break; 3823 if (!it.HasProperty()) break;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
4015 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN); 3976 LookupIterator it(object, name, LookupIterator::CHECK_HIDDEN);
4016 return GetPropertyAttributes(&it); 3977 return GetPropertyAttributes(&it);
4017 } 3978 }
4018 3979
4019 3980
4020 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes( 3981 Maybe<PropertyAttributes> JSReceiver::GetPropertyAttributes(
4021 LookupIterator* it) { 3982 LookupIterator* it) {
4022 for (; it->IsFound(); it->Next()) { 3983 for (; it->IsFound(); it->Next()) {
4023 switch (it->state()) { 3984 switch (it->state()) {
4024 case LookupIterator::NOT_FOUND: 3985 case LookupIterator::NOT_FOUND:
3986 case LookupIterator::TRANSITION:
4025 UNREACHABLE(); 3987 UNREACHABLE();
4026 case LookupIterator::JSPROXY: 3988 case LookupIterator::JSPROXY:
4027 return JSProxy::GetPropertyAttributesWithHandler( 3989 return JSProxy::GetPropertyAttributesWithHandler(
4028 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name()); 3990 it->GetHolder<JSProxy>(), it->GetReceiver(), it->name());
4029 case LookupIterator::INTERCEPTOR: { 3991 case LookupIterator::INTERCEPTOR: {
4030 Maybe<PropertyAttributes> result = 3992 Maybe<PropertyAttributes> result =
4031 JSObject::GetPropertyAttributesWithInterceptor( 3993 JSObject::GetPropertyAttributesWithInterceptor(
4032 it->GetHolder<JSObject>(), it->GetReceiver(), it->name()); 3994 it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
4033 if (!result.has_value) return result; 3995 if (!result.has_value) return result;
4034 if (result.value != ABSENT) return result; 3996 if (result.value != ABSENT) return result;
(...skipping 919 matching lines...) Expand 10 before | Expand all | Expand 10 after
4954 ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR 4916 ? LookupIterator::CHECK_HIDDEN_SKIP_INTERCEPTOR
4955 : LookupIterator::CHECK_HIDDEN; 4917 : LookupIterator::CHECK_HIDDEN;
4956 4918
4957 LookupIterator it(object, name, config); 4919 LookupIterator it(object, name, config);
4958 4920
4959 bool is_observed = object->map()->is_observed() && 4921 bool is_observed = object->map()->is_observed() &&
4960 *name != it.isolate()->heap()->hidden_string(); 4922 *name != it.isolate()->heap()->hidden_string();
4961 4923
4962 for (; it.IsFound(); it.Next()) { 4924 for (; it.IsFound(); it.Next()) {
4963 switch (it.state()) { 4925 switch (it.state()) {
4926 case LookupIterator::JSPROXY:
4964 case LookupIterator::NOT_FOUND: 4927 case LookupIterator::NOT_FOUND:
4965 case LookupIterator::JSPROXY: 4928 case LookupIterator::TRANSITION:
4966 UNREACHABLE(); 4929 UNREACHABLE();
4967 case LookupIterator::ACCESS_CHECK: 4930 case LookupIterator::ACCESS_CHECK:
4968 if (it.HasAccess(v8::ACCESS_DELETE)) break; 4931 if (it.HasAccess(v8::ACCESS_DELETE)) break;
4969 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(), 4932 it.isolate()->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
4970 v8::ACCESS_DELETE); 4933 v8::ACCESS_DELETE);
4971 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object); 4934 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it.isolate(), Object);
4972 return it.isolate()->factory()->false_value(); 4935 return it.isolate()->factory()->false_value();
4973 case LookupIterator::INTERCEPTOR: { 4936 case LookupIterator::INTERCEPTOR: {
4974 MaybeHandle<Object> maybe_result = 4937 MaybeHandle<Object> maybe_result =
4975 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(), 4938 JSObject::DeletePropertyWithInterceptor(it.GetHolder<JSObject>(),
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after
5703 for (int i = 0; i < number_of_own_descriptors; i++) { 5666 for (int i = 0; i < number_of_own_descriptors; i++) {
5704 if (descs->GetType(i) == FIELD) { 5667 if (descs->GetType(i) == FIELD) {
5705 int current_index = descs->GetFieldIndex(i); 5668 int current_index = descs->GetFieldIndex(i);
5706 if (current_index > max_index) max_index = current_index; 5669 if (current_index > max_index) max_index = current_index;
5707 } 5670 }
5708 } 5671 }
5709 return max_index + 1; 5672 return max_index + 1;
5710 } 5673 }
5711 5674
5712 5675
5713 void JSReceiver::LookupOwn(Handle<Name> name, LookupResult* result) {
5714 DisallowHeapAllocation no_gc;
5715 DCHECK(name->IsName());
5716
5717 if (IsJSGlobalProxy()) {
5718 PrototypeIterator iter(GetIsolate(), this);
5719 if (iter.IsAtEnd()) return result->NotFound();
5720 DCHECK(iter.GetCurrent()->IsJSGlobalObject());
5721 return JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result);
5722 }
5723
5724 if (IsJSProxy()) {
5725 result->HandlerResult(JSProxy::cast(this));
5726 return;
5727 }
5728
5729 // Do not use inline caching if the object is a non-global object
5730 // that requires access checks.
5731 if (IsAccessCheckNeeded()) {
5732 result->DisallowCaching();
5733 }
5734
5735 JSObject* js_object = JSObject::cast(this);
5736
5737 // Check for lookup interceptor except when bootstrapping.
5738 if (js_object->HasNamedInterceptor() &&
5739 !GetIsolate()->bootstrapper()->IsActive()) {
5740 result->InterceptorResult(js_object);
5741 return;
5742 }
5743
5744 js_object->LookupOwnRealNamedProperty(name, result);
5745 }
5746
5747
5748 void JSReceiver::Lookup(Handle<Name> name, LookupResult* result) {
5749 DisallowHeapAllocation no_gc;
5750 // Ecma-262 3rd 8.6.2.4
5751 for (PrototypeIterator iter(GetIsolate(), this,
5752 PrototypeIterator::START_AT_RECEIVER);
5753 !iter.IsAtEnd(); iter.Advance()) {
5754 JSReceiver::cast(iter.GetCurrent())->LookupOwn(name, result);
5755 if (result->IsFound()) return;
5756 if (name->IsOwn()) {
5757 result->NotFound();
5758 return;
5759 }
5760 }
5761 result->NotFound();
5762 }
5763
5764
5765 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { 5676 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
5766 int len = array->length(); 5677 int len = array->length();
5767 for (int i = 0; i < len; i++) { 5678 for (int i = 0; i < len; i++) {
5768 Object* e = array->get(i); 5679 Object* e = array->get(i);
5769 if (!(e->IsString() || e->IsNumber())) return false; 5680 if (!(e->IsString() || e->IsNumber())) return false;
5770 } 5681 }
5771 return true; 5682 return true;
5772 } 5683 }
5773 5684
5774 5685
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
6390 isolate); 6301 isolate);
6391 } 6302 }
6392 } 6303 }
6393 } 6304 }
6394 } 6305 }
6395 } else { 6306 } else {
6396 LookupIterator it(object, name, 6307 LookupIterator it(object, name,
6397 LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR); 6308 LookupIterator::CHECK_DERIVED_SKIP_INTERCEPTOR);
6398 for (; it.IsFound(); it.Next()) { 6309 for (; it.IsFound(); it.Next()) {
6399 switch (it.state()) { 6310 switch (it.state()) {
6311 case LookupIterator::INTERCEPTOR:
6400 case LookupIterator::NOT_FOUND: 6312 case LookupIterator::NOT_FOUND:
6401 case LookupIterator::INTERCEPTOR: 6313 case LookupIterator::TRANSITION:
6402 UNREACHABLE(); 6314 UNREACHABLE();
6403 6315
6404 case LookupIterator::ACCESS_CHECK: 6316 case LookupIterator::ACCESS_CHECK:
6405 if (it.HasAccess(v8::ACCESS_HAS)) continue; 6317 if (it.HasAccess(v8::ACCESS_HAS)) continue;
6406 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(), 6318 isolate->ReportFailedAccessCheck(it.GetHolder<JSObject>(),
6407 v8::ACCESS_HAS); 6319 v8::ACCESS_HAS);
6408 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 6320 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
6409 return isolate->factory()->undefined_value(); 6321 return isolate->factory()->undefined_value();
6410 6322
6411 case LookupIterator::JSPROXY: 6323 case LookupIterator::JSPROXY:
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
6828 return false; 6740 return false;
6829 } 6741 }
6830 6742
6831 6743
6832 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor, 6744 Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
6833 Handle<Object> value) { 6745 Handle<Object> value) {
6834 // Dictionaries can store any property value. 6746 // Dictionaries can store any property value.
6835 if (map->is_dictionary_map()) return map; 6747 if (map->is_dictionary_map()) return map;
6836 6748
6837 // Migrate to the newest map before storing the property. 6749 // Migrate to the newest map before storing the property.
6838 if (map->is_deprecated()) map = Update(map); 6750 map = Update(map);
6839 6751
6840 Handle<DescriptorArray> descriptors(map->instance_descriptors()); 6752 Handle<DescriptorArray> descriptors(map->instance_descriptors());
6841 6753
6842 if (descriptors->CanHoldValue(descriptor, *value)) return map; 6754 if (descriptors->CanHoldValue(descriptor, *value)) return map;
6843 6755
6844 Isolate* isolate = map->GetIsolate(); 6756 Isolate* isolate = map->GetIsolate();
6845 Representation representation = value->OptimalRepresentation(); 6757 Representation representation = value->OptimalRepresentation();
6846 Handle<HeapType> type = value->OptimalType(isolate, representation); 6758 Handle<HeapType> type = value->OptimalType(isolate, representation);
6847 6759
6848 return GeneralizeRepresentation(map, descriptor, representation, type, 6760 return GeneralizeRepresentation(map, descriptor, representation, type,
6849 FORCE_FIELD); 6761 FORCE_FIELD);
6850 } 6762 }
6851 6763
6852 6764
6853 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name, 6765 Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
6854 Handle<Object> value, 6766 Handle<Object> value,
6855 PropertyAttributes attributes, 6767 PropertyAttributes attributes,
6856 StoreFromKeyed store_mode) { 6768 StoreFromKeyed store_mode) {
6857 // Dictionary maps can always have additional data properties. 6769 // Dictionary maps can always have additional data properties.
6858 if (map->is_dictionary_map()) return map; 6770 if (map->is_dictionary_map()) return map;
6859 6771
6860 // Migrate to the newest map before transitioning to the new property. 6772 // Migrate to the newest map before storing the property.
6861 if (map->is_deprecated()) map = Update(map); 6773 map = Update(map);
6862 6774
6863 int index = map->SearchTransition(*name); 6775 int index = map->SearchTransition(*name);
6864 if (index != TransitionArray::kNotFound) { 6776 if (index != TransitionArray::kNotFound) {
6865 Handle<Map> transition(map->GetTransition(index)); 6777 Handle<Map> transition(map->GetTransition(index));
6866 int descriptor = transition->LastAdded(); 6778 int descriptor = transition->LastAdded();
6867 6779
6868 // TODO(verwaest): Handle attributes better. 6780 // TODO(verwaest): Handle attributes better.
6869 DescriptorArray* descriptors = transition->instance_descriptors(); 6781 DescriptorArray* descriptors = transition->instance_descriptors();
6870 if (descriptors->GetDetails(descriptor).attributes() != attributes) { 6782 if (descriptors->GetDetails(descriptor).attributes() != attributes) {
6871 return CopyGeneralizeAllRepresentations(transition, descriptor, 6783 return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
6872 FORCE_FIELD, attributes,
6873 "attributes mismatch");
6874 } 6784 }
6875 6785
6876 return Map::PrepareForDataProperty(transition, descriptor, value); 6786 return Map::PrepareForDataProperty(transition, descriptor, value);
6877 } 6787 }
6878 6788
6879 TransitionFlag flag = INSERT_TRANSITION; 6789 TransitionFlag flag = INSERT_TRANSITION;
6880 MaybeHandle<Map> maybe_map; 6790 MaybeHandle<Map> maybe_map;
6881 if (value->IsJSFunction()) { 6791 if (value->IsJSFunction()) {
6882 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag); 6792 maybe_map = Map::CopyWithConstant(map, name, value, attributes, flag);
6883 } else if (!map->TooManyFastProperties(store_mode)) { 6793 } else if (!map->TooManyFastProperties(store_mode)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
6918 6828
6919 // Dictionary maps can always have additional data properties. 6829 // Dictionary maps can always have additional data properties.
6920 if (map->is_dictionary_map()) { 6830 if (map->is_dictionary_map()) {
6921 // For global objects, property cells are inlined. We need to change the 6831 // For global objects, property cells are inlined. We need to change the
6922 // map. 6832 // map.
6923 if (map->IsGlobalObjectMap()) return Copy(map); 6833 if (map->IsGlobalObjectMap()) return Copy(map);
6924 return map; 6834 return map;
6925 } 6835 }
6926 6836
6927 // Migrate to the newest map before transitioning to the new property. 6837 // Migrate to the newest map before transitioning to the new property.
6928 if (map->is_deprecated()) map = Update(map); 6838 map = Update(map);
6929 6839
6930 PropertyNormalizationMode mode = map->is_prototype_map() 6840 PropertyNormalizationMode mode = map->is_prototype_map()
6931 ? KEEP_INOBJECT_PROPERTIES 6841 ? KEEP_INOBJECT_PROPERTIES
6932 : CLEAR_INOBJECT_PROPERTIES; 6842 : CLEAR_INOBJECT_PROPERTIES;
6933 6843
6934 int index = map->SearchTransition(*name); 6844 int index = map->SearchTransition(*name);
6935 if (index != TransitionArray::kNotFound) { 6845 if (index != TransitionArray::kNotFound) {
6936 Handle<Map> transition(map->GetTransition(index)); 6846 Handle<Map> transition(map->GetTransition(index));
6937 DescriptorArray* descriptors = transition->instance_descriptors(); 6847 DescriptorArray* descriptors = transition->instance_descriptors();
6938 // Fast path, assume that we're modifying the last added descriptor. 6848 // Fast path, assume that we're modifying the last added descriptor.
(...skipping 9588 matching lines...) Expand 10 before | Expand all | Expand 10 after
16527 #define ERROR_MESSAGES_TEXTS(C, T) T, 16437 #define ERROR_MESSAGES_TEXTS(C, T) T,
16528 static const char* error_messages_[] = { 16438 static const char* error_messages_[] = {
16529 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16439 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16530 }; 16440 };
16531 #undef ERROR_MESSAGES_TEXTS 16441 #undef ERROR_MESSAGES_TEXTS
16532 return error_messages_[reason]; 16442 return error_messages_[reason];
16533 } 16443 }
16534 16444
16535 16445
16536 } } // namespace v8::internal 16446 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698