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

Side by Side Diff: src/lookup.cc

Issue 490533002: Use LookupIterator to transition to accessors (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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/lookup.h ('k') | src/lookup-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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/deoptimizer.h"
8 #include "src/lookup.h" 9 #include "src/lookup.h"
9 #include "src/lookup-inl.h" 10 #include "src/lookup-inl.h"
10 11
11 namespace v8 { 12 namespace v8 {
12 namespace internal { 13 namespace internal {
13 14
14 15
15 void LookupIterator::Next() { 16 void LookupIterator::Next() {
16 DisallowHeapAllocation no_gc; 17 DisallowHeapAllocation no_gc;
17 has_property_ = false; 18 has_property_ = false;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 case v8::internal::NONEXISTENT: 103 case v8::internal::NONEXISTENT:
103 case v8::internal::INTERCEPTOR: 104 case v8::internal::INTERCEPTOR:
104 UNREACHABLE(); 105 UNREACHABLE();
105 } 106 }
106 107
107 has_property_ = true; 108 has_property_ = true;
108 return true; 109 return true;
109 } 110 }
110 111
111 112
113 void LookupIterator::ReloadPropertyInformation() {
114 state_ = BEFORE_PROPERTY;
115 state_ = LookupInHolder(*holder_map_);
116 DCHECK(IsFound());
117 HasProperty();
118 }
119
120
112 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { 121 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
113 DCHECK(has_property_); 122 DCHECK(has_property_);
114 DCHECK(HolderIsReceiverOrHiddenPrototype()); 123 DCHECK(HolderIsReceiverOrHiddenPrototype());
115 if (property_encoding_ == DICTIONARY) return; 124 if (property_encoding_ == DICTIONARY) return;
116 holder_map_ = 125 holder_map_ =
117 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); 126 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
118 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); 127 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_);
119 // Reload property information. 128 ReloadPropertyInformation();
120 if (holder_map_->is_dictionary_map()) {
121 property_encoding_ = DICTIONARY;
122 } else {
123 property_encoding_ = DESCRIPTOR;
124 }
125 CHECK(HasProperty());
126 } 129 }
127 130
128 131
129 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, 132 void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
130 PropertyAttributes attributes) { 133 PropertyAttributes attributes) {
131 DCHECK(has_property_); 134 DCHECK(has_property_);
132 DCHECK(HolderIsReceiverOrHiddenPrototype()); 135 DCHECK(HolderIsReceiverOrHiddenPrototype());
133 Handle<JSObject> holder = GetHolder<JSObject>(); 136 Handle<JSObject> holder = GetHolder<JSObject>();
134 if (property_encoding_ != DICTIONARY) { 137 if (property_encoding_ != DICTIONARY) {
135 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(), 138 holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(),
136 attributes); 139 attributes);
137 JSObject::MigrateToMap(holder, holder_map_); 140 JSObject::MigrateToMap(holder, holder_map_);
138 } 141 }
139 142
140 // Reload property information and update the descriptor if in dictionary
141 // mode.
142 if (holder_map_->is_dictionary_map()) { 143 if (holder_map_->is_dictionary_map()) {
143 property_encoding_ = DICTIONARY;
144 PropertyDetails details(attributes, NORMAL, 0); 144 PropertyDetails details(attributes, NORMAL, 0);
145 JSObject::SetNormalizedProperty(holder, name(), value, details); 145 JSObject::SetNormalizedProperty(holder, name(), value, details);
146 } else {
147 property_encoding_ = DESCRIPTOR;
148 } 146 }
149 147
150 CHECK(HasProperty()); 148 ReloadPropertyInformation();
151 } 149 }
152 150
153 151
154 void LookupIterator::TransitionToDataProperty( 152 void LookupIterator::TransitionToDataProperty(
155 Handle<Object> value, PropertyAttributes attributes, 153 Handle<Object> value, PropertyAttributes attributes,
156 Object::StoreFromKeyed store_mode) { 154 Object::StoreFromKeyed store_mode) {
157 DCHECK(!has_property_ || !HolderIsReceiverOrHiddenPrototype()); 155 DCHECK(!has_property_ || !HolderIsReceiverOrHiddenPrototype());
158 156
159 // Can only be called when the receiver is a JSObject. JSProxy has to be 157 // Can only be called when the receiver is a JSObject. JSProxy has to be
160 // handled via a trap. Adding properties to primitive values is not 158 // handled via a trap. Adding properties to primitive values is not
161 // observable. 159 // observable.
162 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); 160 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
163 161
164 if (receiver->IsJSGlobalProxy()) { 162 if (receiver->IsJSGlobalProxy()) {
165 PrototypeIterator iter(isolate(), receiver); 163 PrototypeIterator iter(isolate(), receiver);
166 receiver = 164 receiver =
167 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)); 165 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
168 } 166 }
169 167
170 maybe_holder_ = receiver; 168 maybe_holder_ = receiver;
171 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_, 169 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_,
172 value, attributes, store_mode); 170 value, attributes, store_mode);
173 JSObject::MigrateToMap(receiver, holder_map_); 171 JSObject::MigrateToMap(receiver, holder_map_);
174 172
175 // Reload the information. 173 ReloadPropertyInformation();
176 state_ = NOT_FOUND;
177 configuration_ = CHECK_PROPERTY;
178 state_ = LookupInHolder(*holder_map_);
179 DCHECK(IsFound());
180 HasProperty();
181 } 174 }
182 175
183 176
177 void LookupIterator::TransitionToAccessorProperty(
178 AccessorComponent component, Handle<Object> accessor,
179 PropertyAttributes attributes) {
180 DCHECK(!accessor->IsNull());
181 // Can only be called when the receiver is a JSObject. JSProxy has to be
182 // handled via a trap. Adding properties to primitive values is not
183 // observable.
184 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
185
186 if (receiver->IsJSGlobalProxy()) {
187 PrototypeIterator iter(isolate(), receiver);
188 receiver =
189 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter));
190 }
191
192 maybe_holder_ = receiver;
193 holder_map_ = Map::TransitionToAccessorProperty(
194 handle(receiver->map()), name_, component, accessor, attributes);
195 JSObject::MigrateToMap(receiver, holder_map_);
196
197 ReloadPropertyInformation();
198
199 if (!holder_map_->is_dictionary_map()) return;
200
201 // We have to deoptimize since accesses to data properties may have been
202 // inlined without a corresponding map-check.
203 if (holder_map_->IsGlobalObjectMap()) {
204 Deoptimizer::DeoptimizeGlobalObject(*receiver);
205 }
206
207 // Install the accessor into the dictionary-mode object.
208 PropertyDetails details(attributes, CALLBACKS, 0);
209 Handle<AccessorPair> pair;
210 if (IsFound() && HasProperty() && property_kind() == ACCESSOR &&
211 GetAccessors()->IsAccessorPair()) {
212 pair = Handle<AccessorPair>::cast(GetAccessors());
213 // If the component and attributes are identical, nothing has to be done.
214 if (pair->get(component) == *accessor) {
215 if (property_details().attributes() == attributes) return;
216 } else {
217 pair = AccessorPair::Copy(pair);
218 pair->set(component, *accessor);
219 }
220 } else {
221 pair = isolate()->factory()->NewAccessorPair();
222 pair->set(component, *accessor);
223 }
224 JSObject::SetNormalizedProperty(receiver, name_, pair, details);
225
226 JSObject::ReoptimizeIfPrototype(receiver);
227 holder_map_ = handle(receiver->map());
228 ReloadPropertyInformation();
229 }
230
231
184 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { 232 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
185 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); 233 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
186 // Optimization that only works if configuration_ is not mutable. 234 // Optimization that only works if configuration_ is not mutable.
187 if (!check_derived()) return true; 235 if (!check_derived()) return true;
188 DisallowHeapAllocation no_gc; 236 DisallowHeapAllocation no_gc;
189 Handle<Object> receiver = GetReceiver(); 237 Handle<Object> receiver = GetReceiver();
190 if (!receiver->IsJSReceiver()) return false; 238 if (!receiver->IsJSReceiver()) return false;
191 Object* current = *receiver; 239 Object* current = *receiver;
192 JSReceiver* holder = *maybe_holder_.ToHandleChecked(); 240 JSReceiver* holder = *maybe_holder_.ToHandleChecked();
193 // JSProxy do not occur as hidden prototypes. 241 // JSProxy do not occur as hidden prototypes.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type()); 347 DCHECK_EQ(v8::internal::CONSTANT, property_details_.type());
300 } 348 }
301 } 349 }
302 350
303 351
304 void LookupIterator::InternalizeName() { 352 void LookupIterator::InternalizeName() {
305 if (name_->IsUniqueName()) return; 353 if (name_->IsUniqueName()) return;
306 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 354 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
307 } 355 }
308 } } // namespace v8::internal 356 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lookup.h ('k') | src/lookup-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698