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

Side by Side Diff: src/lookup.cc

Issue 429053005: Avoid one repeated property lookup when computing load ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebased 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/mips/stub-cache-mips.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 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/lookup.h" 8 #include "src/lookup.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 number_ = holder->property_dictionary()->FindEntry(name_); 113 number_ = holder->property_dictionary()->FindEntry(name_);
114 if (number_ == NameDictionary::kNotFound) return false; 114 if (number_ == NameDictionary::kNotFound) return false;
115 115
116 property_details_ = holder->property_dictionary()->DetailsAt(number_); 116 property_details_ = holder->property_dictionary()->DetailsAt(number_);
117 // Holes in dictionary cells are absent values. 117 // Holes in dictionary cells are absent values.
118 if (holder->IsGlobalObject() && 118 if (holder->IsGlobalObject() &&
119 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) { 119 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
120 return false; 120 return false;
121 } 121 }
122 } else { 122 } else {
123 property_details_ = holder_map_->instance_descriptors()->GetDetails( 123 // Can't use descriptor_number() yet because has_property_ is still false.
124 number_); 124 property_details_ =
125 holder_map_->instance_descriptors()->GetDetails(number_);
125 } 126 }
126 127
127 switch (property_details_.type()) { 128 switch (property_details_.type()) {
128 case v8::internal::FIELD: 129 case v8::internal::FIELD:
129 case v8::internal::NORMAL: 130 case v8::internal::NORMAL:
130 case v8::internal::CONSTANT: 131 case v8::internal::CONSTANT:
131 property_kind_ = DATA; 132 property_kind_ = DATA;
132 break; 133 break;
133 case v8::internal::CALLBACKS: 134 case v8::internal::CALLBACKS:
134 property_kind_ = ACCESSOR; 135 property_kind_ = ACCESSOR;
135 break; 136 break;
136 case v8::internal::HANDLER: 137 case v8::internal::HANDLER:
137 case v8::internal::NONEXISTENT: 138 case v8::internal::NONEXISTENT:
138 case v8::internal::INTERCEPTOR: 139 case v8::internal::INTERCEPTOR:
139 UNREACHABLE(); 140 UNREACHABLE();
140 } 141 }
141 142
142 has_property_ = true; 143 has_property_ = true;
143 return true; 144 return true;
144 } 145 }
145 146
146 147
147 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { 148 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
148 ASSERT(has_property_); 149 ASSERT(has_property_);
149 ASSERT(HolderIsReceiver()); 150 ASSERT(HolderIsReceiverOrHiddenPrototype());
150 if (property_encoding_ == DICTIONARY) return; 151 if (property_encoding_ == DICTIONARY) return;
151 holder_map_ = Map::PrepareForDataProperty(holder_map_, number_, value); 152 holder_map_ =
153 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value);
152 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_); 154 JSObject::MigrateToMap(GetHolder<JSObject>(), holder_map_);
153 // Reload property information. 155 // Reload property information.
154 if (holder_map_->is_dictionary_map()) { 156 if (holder_map_->is_dictionary_map()) {
155 property_encoding_ = DICTIONARY; 157 property_encoding_ = DICTIONARY;
156 } else { 158 } else {
157 property_encoding_ = DESCRIPTOR; 159 property_encoding_ = DESCRIPTOR;
158 } 160 }
159 CHECK(HasProperty()); 161 CHECK(HasProperty());
160 } 162 }
161 163
162 164
163 void LookupIterator::TransitionToDataProperty( 165 void LookupIterator::TransitionToDataProperty(
164 Handle<Object> value, PropertyAttributes attributes, 166 Handle<Object> value, PropertyAttributes attributes,
165 Object::StoreFromKeyed store_mode) { 167 Object::StoreFromKeyed store_mode) {
166 ASSERT(!has_property_ || !HolderIsReceiver()); 168 ASSERT(!has_property_ || !HolderIsReceiverOrHiddenPrototype());
167 169
168 // Can only be called when the receiver is a JSObject. JSProxy has to be 170 // Can only be called when the receiver is a JSObject. JSProxy has to be
169 // handled via a trap. Adding properties to primitive values is not 171 // handled via a trap. Adding properties to primitive values is not
170 // observable. 172 // observable.
171 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver()); 173 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
172 174
173 // Properties have to be added to context extension objects through 175 // Properties have to be added to context extension objects through
174 // SetOwnPropertyIgnoreAttributes. 176 // SetOwnPropertyIgnoreAttributes.
175 ASSERT(!receiver->IsJSContextExtensionObject()); 177 ASSERT(!receiver->IsJSContextExtensionObject());
176 178
(...skipping 10 matching lines...) Expand all
187 189
188 // Reload the information. 190 // Reload the information.
189 state_ = NOT_FOUND; 191 state_ = NOT_FOUND;
190 configuration_ = CHECK_OWN_REAL; 192 configuration_ = CHECK_OWN_REAL;
191 state_ = LookupInHolder(); 193 state_ = LookupInHolder();
192 ASSERT(IsFound()); 194 ASSERT(IsFound());
193 HasProperty(); 195 HasProperty();
194 } 196 }
195 197
196 198
197 bool LookupIterator::HolderIsReceiver() const { 199 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
198 ASSERT(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); 200 ASSERT(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
199 DisallowHeapAllocation no_gc; 201 DisallowHeapAllocation no_gc;
200 Handle<Object> receiver = GetReceiver(); 202 Handle<Object> receiver = GetReceiver();
201 if (!receiver->IsJSReceiver()) return false; 203 if (!receiver->IsJSReceiver()) return false;
202 Object* current = *receiver; 204 Object* current = *receiver;
203 JSReceiver* holder = *maybe_holder_.ToHandleChecked(); 205 JSReceiver* holder = *maybe_holder_.ToHandleChecked();
204 // JSProxy do not occur as hidden prototypes. 206 // JSProxy do not occur as hidden prototypes.
205 if (current->IsJSProxy()) { 207 if (current->IsJSProxy()) {
206 return JSReceiver::cast(current) == holder; 208 return JSReceiver::cast(current) == holder;
207 } 209 }
(...skipping 13 matching lines...) Expand all
221 Handle<JSObject> holder = GetHolder<JSObject>(); 223 Handle<JSObject> holder = GetHolder<JSObject>();
222 switch (property_encoding_) { 224 switch (property_encoding_) {
223 case DICTIONARY: 225 case DICTIONARY:
224 result = holder->property_dictionary()->ValueAt(number_); 226 result = holder->property_dictionary()->ValueAt(number_);
225 if (holder->IsGlobalObject()) { 227 if (holder->IsGlobalObject()) {
226 result = PropertyCell::cast(result)->value(); 228 result = PropertyCell::cast(result)->value();
227 } 229 }
228 break; 230 break;
229 case DESCRIPTOR: 231 case DESCRIPTOR:
230 if (property_details_.type() == v8::internal::FIELD) { 232 if (property_details_.type() == v8::internal::FIELD) {
231 FieldIndex field_index = FieldIndex::ForDescriptor( 233 FieldIndex field_index =
232 *holder_map_, number_); 234 FieldIndex::ForDescriptor(*holder_map_, number_);
233 return JSObject::FastPropertyAt( 235 return JSObject::FastPropertyAt(
234 holder, property_details_.representation(), field_index); 236 holder, property_details_.representation(), field_index);
235 } 237 }
236 result = holder_map_->instance_descriptors()->GetValue(number_); 238 result = holder_map_->instance_descriptors()->GetValue(number_);
237 } 239 }
238 return handle(result, isolate_); 240 return handle(result, isolate_);
239 } 241 }
240 242
241 243
244 FieldIndex LookupIterator::GetFieldIndex() const {
245 ASSERT_EQ(PROPERTY, state_);
246 int index =
247 holder_map()->instance_descriptors()->GetFieldIndex(descriptor_number());
248 bool is_double = representation().IsDouble();
249 return FieldIndex::ForPropertyIndex(*holder_map(), index, is_double);
250 }
251
252
253 Handle<PropertyCell> LookupIterator::GetPropertyCell() const {
254 Handle<JSObject> holder = GetHolder<JSObject>();
255 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
256 Object* value = global->property_dictionary()->ValueAt(dictionary_entry());
257 return Handle<PropertyCell>(PropertyCell::cast(value));
258 }
259
260
242 Handle<Object> LookupIterator::GetAccessors() const { 261 Handle<Object> LookupIterator::GetAccessors() const {
243 ASSERT(has_property_); 262 ASSERT(has_property_);
244 ASSERT_EQ(ACCESSOR, property_kind_); 263 ASSERT_EQ(ACCESSOR, property_kind_);
245 return FetchValue(); 264 return FetchValue();
246 } 265 }
247 266
248 267
249 Handle<Object> LookupIterator::GetDataValue() const { 268 Handle<Object> LookupIterator::GetDataValue() const {
250 ASSERT(has_property_); 269 ASSERT(has_property_);
251 ASSERT_EQ(DATA, property_kind_); 270 ASSERT_EQ(DATA, property_kind_);
252 Handle<Object> value = FetchValue(); 271 Handle<Object> value = FetchValue();
253 return value; 272 return value;
254 } 273 }
255 274
256 275
257 void LookupIterator::WriteDataValue(Handle<Object> value) { 276 void LookupIterator::WriteDataValue(Handle<Object> value) {
258 ASSERT(is_guaranteed_to_have_holder()); 277 ASSERT(is_guaranteed_to_have_holder());
259 ASSERT(has_property_); 278 ASSERT(has_property_);
260 Handle<JSObject> holder = GetHolder<JSObject>(); 279 Handle<JSObject> holder = GetHolder<JSObject>();
261 if (property_encoding_ == DICTIONARY) { 280 if (property_encoding_ == DICTIONARY) {
262 NameDictionary* property_dictionary = holder->property_dictionary(); 281 NameDictionary* property_dictionary = holder->property_dictionary();
263 if (holder->IsGlobalObject()) { 282 if (holder->IsGlobalObject()) {
264 Handle<PropertyCell> cell( 283 Handle<PropertyCell> cell(
265 PropertyCell::cast(property_dictionary->ValueAt(number_))); 284 PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry())));
266 PropertyCell::SetValueInferType(cell, value); 285 PropertyCell::SetValueInferType(cell, value);
267 } else { 286 } else {
268 property_dictionary->ValueAtPut(number_, *value); 287 property_dictionary->ValueAtPut(dictionary_entry(), *value);
269 } 288 }
270 } else if (property_details_.type() == v8::internal::FIELD) { 289 } else if (property_details_.type() == v8::internal::FIELD) {
271 holder->WriteToField(number_, *value); 290 holder->WriteToField(descriptor_number(), *value);
272 } else { 291 } else {
273 ASSERT_EQ(v8::internal::CONSTANT, property_details_.type()); 292 ASSERT_EQ(v8::internal::CONSTANT, property_details_.type());
274 } 293 }
275 } 294 }
276 295
277 296
278 void LookupIterator::InternalizeName() { 297 void LookupIterator::InternalizeName() {
279 if (name_->IsUniqueName()) return; 298 if (name_->IsUniqueName()) return;
280 name_ = factory()->InternalizeString(Handle<String>::cast(name_)); 299 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
281 } 300 }
282 } } // namespace v8::internal 301 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lookup.h ('k') | src/mips/stub-cache-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698