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

Side by Side Diff: src/property.h

Issue 223193005: Get rid of the TRANSITION PropertyType and consistently use CanHoldValue(). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Use number_ for LastAdded in transition results. Created 6 years, 8 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-printer.cc ('k') | src/property.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 #ifndef V8_PROPERTY_H_ 5 #ifndef V8_PROPERTY_H_
6 #define V8_PROPERTY_H_ 6 #define V8_PROPERTY_H_
7 7
8 #include "isolate.h" 8 #include "isolate.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) { 173 void DescriptorResult(JSObject* holder, PropertyDetails details, int number) {
174 lookup_type_ = DESCRIPTOR_TYPE; 174 lookup_type_ = DESCRIPTOR_TYPE;
175 holder_ = holder; 175 holder_ = holder;
176 transition_ = NULL; 176 transition_ = NULL;
177 details_ = details; 177 details_ = details;
178 number_ = number; 178 number_ = number;
179 } 179 }
180 180
181 bool CanHoldValue(Handle<Object> value) { 181 bool CanHoldValue(Handle<Object> value) {
182 if (IsNormal()) return true; 182 if (IsNormal()) return true;
183 ASSERT(!IsTransition());
184 return value->FitsRepresentation(details_.representation()); 183 return value->FitsRepresentation(details_.representation());
185 } 184 }
186 185
187 void TransitionResult(JSObject* holder, Map* target) { 186 void TransitionResult(JSObject* holder, Map* target) {
188 lookup_type_ = TRANSITION_TYPE; 187 lookup_type_ = TRANSITION_TYPE;
189 details_ = PropertyDetails(NONE, TRANSITION, Representation::None()); 188 number_ = target->LastAdded();
189 details_ = target->instance_descriptors()->GetDetails(number_);
190 holder_ = holder; 190 holder_ = holder;
191 transition_ = target; 191 transition_ = target;
192 number_ = 0xAAAA;
193 } 192 }
194 193
195 void DictionaryResult(JSObject* holder, int entry) { 194 void DictionaryResult(JSObject* holder, int entry) {
196 lookup_type_ = DICTIONARY_TYPE; 195 lookup_type_ = DICTIONARY_TYPE;
197 holder_ = holder; 196 holder_ = holder;
198 transition_ = NULL; 197 transition_ = NULL;
199 details_ = holder->property_dictionary()->DetailsAt(entry); 198 details_ = holder->property_dictionary()->DetailsAt(entry);
200 number_ = entry; 199 number_ = entry;
201 } 200 }
202 201
(...skipping 29 matching lines...) Expand all
232 return JSProxy::cast(holder_); 231 return JSProxy::cast(holder_);
233 } 232 }
234 233
235 PropertyType type() const { 234 PropertyType type() const {
236 ASSERT(IsFound()); 235 ASSERT(IsFound());
237 return details_.type(); 236 return details_.type();
238 } 237 }
239 238
240 Representation representation() const { 239 Representation representation() const {
241 ASSERT(IsFound()); 240 ASSERT(IsFound());
242 ASSERT(!IsTransition());
243 ASSERT(details_.type() != NONEXISTENT); 241 ASSERT(details_.type() != NONEXISTENT);
244 return details_.representation(); 242 return details_.representation();
245 } 243 }
246 244
247 PropertyAttributes GetAttributes() const { 245 PropertyAttributes GetAttributes() const {
248 ASSERT(!IsTransition());
249 ASSERT(IsFound()); 246 ASSERT(IsFound());
250 ASSERT(details_.type() != NONEXISTENT); 247 ASSERT(details_.type() != NONEXISTENT);
251 return details_.attributes(); 248 return details_.attributes();
252 } 249 }
253 250
254 PropertyDetails GetPropertyDetails() const { 251 PropertyDetails GetPropertyDetails() const {
255 ASSERT(!IsTransition());
256 return details_; 252 return details_;
257 } 253 }
258 254
259 bool IsFastPropertyType() const { 255 bool IsFastPropertyType() const {
260 ASSERT(IsFound()); 256 ASSERT(IsFound());
261 return IsTransition() || type() != NORMAL; 257 return IsTransition() || type() != NORMAL;
262 } 258 }
263 259
264 // Property callbacks does not include transitions to callbacks. 260 // Property callbacks does not include transitions to callbacks.
265 bool IsPropertyCallbacks() const { 261 bool IsPropertyCallbacks() const {
266 ASSERT(!(details_.type() == CALLBACKS && !IsFound())); 262 ASSERT(!(details_.type() == CALLBACKS && !IsFound()));
267 return details_.type() == CALLBACKS; 263 return !IsTransition() && details_.type() == CALLBACKS;
268 } 264 }
269 265
270 bool IsReadOnly() const { 266 bool IsReadOnly() const {
271 ASSERT(IsFound()); 267 ASSERT(IsFound());
272 ASSERT(!IsTransition());
273 ASSERT(details_.type() != NONEXISTENT); 268 ASSERT(details_.type() != NONEXISTENT);
274 return details_.IsReadOnly(); 269 return details_.IsReadOnly();
275 } 270 }
276 271
277 bool IsField() const { 272 bool IsField() const {
278 ASSERT(!(details_.type() == FIELD && !IsFound())); 273 ASSERT(!(details_.type() == FIELD && !IsFound()));
279 return details_.type() == FIELD; 274 return IsDescriptorOrDictionary() && type() == FIELD;
280 } 275 }
281 276
282 bool IsNormal() const { 277 bool IsNormal() const {
283 ASSERT(!(details_.type() == NORMAL && !IsFound())); 278 ASSERT(!(details_.type() == NORMAL && !IsFound()));
284 return details_.type() == NORMAL; 279 return IsDescriptorOrDictionary() && type() == NORMAL;
285 } 280 }
286 281
287 bool IsConstant() const { 282 bool IsConstant() const {
288 ASSERT(!(details_.type() == CONSTANT && !IsFound())); 283 ASSERT(!(details_.type() == CONSTANT && !IsFound()));
289 return details_.type() == CONSTANT; 284 return IsDescriptorOrDictionary() && type() == CONSTANT;
290 } 285 }
291 286
292 bool IsConstantFunction() const { 287 bool IsConstantFunction() const {
293 return IsConstant() && GetValue()->IsJSFunction(); 288 return IsConstant() && GetConstant()->IsJSFunction();
294 } 289 }
295 290
296 bool IsDontDelete() const { return details_.IsDontDelete(); } 291 bool IsDontDelete() const { return details_.IsDontDelete(); }
297 bool IsDontEnum() const { return details_.IsDontEnum(); } 292 bool IsDontEnum() const { return details_.IsDontEnum(); }
298 bool IsFound() const { return lookup_type_ != NOT_FOUND; } 293 bool IsFound() const { return lookup_type_ != NOT_FOUND; }
294 bool IsDescriptorOrDictionary() const {
295 return lookup_type_ == DESCRIPTOR_TYPE || lookup_type_ == DICTIONARY_TYPE;
296 }
299 bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; } 297 bool IsTransition() const { return lookup_type_ == TRANSITION_TYPE; }
300 bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; } 298 bool IsHandler() const { return lookup_type_ == HANDLER_TYPE; }
301 bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; } 299 bool IsInterceptor() const { return lookup_type_ == INTERCEPTOR_TYPE; }
302 300
303 // Is the result is a property excluding transitions and the null descriptor? 301 // Is the result is a property excluding transitions and the null descriptor?
304 bool IsProperty() const { 302 bool IsProperty() const {
305 return IsFound() && !IsTransition(); 303 return IsFound() && !IsTransition();
306 } 304 }
307 305
308 bool IsDataProperty() const { 306 bool IsDataProperty() const {
309 switch (type()) { 307 switch (lookup_type_) {
310 case FIELD: 308 case NOT_FOUND:
311 case NORMAL: 309 case TRANSITION_TYPE:
312 case CONSTANT: 310 case HANDLER_TYPE:
313 return true; 311 case INTERCEPTOR_TYPE:
314 case CALLBACKS: {
315 Object* callback = GetCallbackObject();
316 return callback->IsAccessorInfo() || callback->IsForeign();
317 }
318 case HANDLER:
319 case INTERCEPTOR:
320 case TRANSITION:
321 case NONEXISTENT:
322 return false; 312 return false;
313
314 case DESCRIPTOR_TYPE:
315 case DICTIONARY_TYPE:
316 switch (type()) {
317 case FIELD:
318 case NORMAL:
319 case CONSTANT:
320 return true;
321 case CALLBACKS: {
322 Object* callback = GetCallbackObject();
323 return callback->IsAccessorInfo() || callback->IsForeign();
324 }
325 case HANDLER:
326 case INTERCEPTOR:
327 case NONEXISTENT:
328 UNREACHABLE();
329 return false;
330 }
323 } 331 }
324 UNREACHABLE(); 332 UNREACHABLE();
325 return false; 333 return false;
326 } 334 }
327 335
328 bool IsCacheable() const { return cacheable_; } 336 bool IsCacheable() const { return cacheable_; }
329 void DisallowCaching() { cacheable_ = false; } 337 void DisallowCaching() { cacheable_ = false; }
330 338
331 Object* GetLazyValue() const { 339 Object* GetLazyValue() const {
332 switch (type()) { 340 switch (lookup_type_) {
333 case FIELD: 341 case NOT_FOUND:
334 return holder()->RawFastPropertyAt(GetFieldIndex().field_index()); 342 case TRANSITION_TYPE:
335 case NORMAL: { 343 case HANDLER_TYPE:
336 Object* value; 344 case INTERCEPTOR_TYPE:
337 value = holder()->property_dictionary()->ValueAt(GetDictionaryEntry()); 345 return isolate()->heap()->the_hole_value();
338 if (holder()->IsGlobalObject()) { 346
339 value = PropertyCell::cast(value)->value(); 347 case DESCRIPTOR_TYPE:
348 case DICTIONARY_TYPE:
349 switch (type()) {
350 case FIELD:
351 return holder()->RawFastPropertyAt(GetFieldIndex().field_index());
352 case NORMAL: {
353 Object* value = holder()->property_dictionary()->ValueAt(
354 GetDictionaryEntry());
355 if (holder()->IsGlobalObject()) {
356 value = PropertyCell::cast(value)->value();
357 }
358 return value;
359 }
360 case CONSTANT:
361 return GetConstant();
362 case CALLBACKS:
363 return isolate()->heap()->the_hole_value();
364 case HANDLER:
365 case INTERCEPTOR:
366 case NONEXISTENT:
367 UNREACHABLE();
368 return NULL;
340 } 369 }
341 return value;
342 }
343 case CONSTANT:
344 return GetConstant();
345 case CALLBACKS:
346 case HANDLER:
347 case INTERCEPTOR:
348 case TRANSITION:
349 case NONEXISTENT:
350 return isolate()->heap()->the_hole_value();
351 } 370 }
352 UNREACHABLE(); 371 UNREACHABLE();
353 return NULL; 372 return NULL;
354 } 373 }
355 374
356 Map* GetTransitionTarget() const { 375 Map* GetTransitionTarget() const {
376 ASSERT(IsTransition());
357 return transition_; 377 return transition_;
358 } 378 }
359 379
360 PropertyDetails GetTransitionDetails() const {
361 ASSERT(IsTransition());
362 return transition_->GetLastDescriptorDetails();
363 }
364
365 bool IsTransitionToField() const { 380 bool IsTransitionToField() const {
366 return IsTransition() && GetTransitionDetails().type() == FIELD; 381 return IsTransition() && details_.type() == FIELD;
367 } 382 }
368 383
369 bool IsTransitionToConstant() const { 384 bool IsTransitionToConstant() const {
370 return IsTransition() && GetTransitionDetails().type() == CONSTANT; 385 return IsTransition() && details_.type() == CONSTANT;
371 } 386 }
372 387
373 int GetDescriptorIndex() const { 388 int GetDescriptorIndex() const {
374 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); 389 ASSERT(lookup_type_ == DESCRIPTOR_TYPE);
375 return number_; 390 return number_;
376 } 391 }
377 392
378 PropertyIndex GetFieldIndex() const { 393 PropertyIndex GetFieldIndex() const {
379 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); 394 ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
395 lookup_type_ == TRANSITION_TYPE);
380 return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map())); 396 return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map()));
381 } 397 }
382 398
383 int GetLocalFieldIndexFromMap(Map* map) const { 399 int GetLocalFieldIndexFromMap(Map* map) const {
384 return GetFieldIndexFromMap(map) - map->inobject_properties(); 400 return GetFieldIndexFromMap(map) - map->inobject_properties();
385 } 401 }
386 402
387 int GetDictionaryEntry() const { 403 int GetDictionaryEntry() const {
388 ASSERT(lookup_type_ == DICTIONARY_TYPE); 404 ASSERT(lookup_type_ == DICTIONARY_TYPE);
389 return number_; 405 return number_;
(...skipping 12 matching lines...) Expand all
402 JSFunction* GetConstantFunctionFromMap(Map* map) const { 418 JSFunction* GetConstantFunctionFromMap(Map* map) const {
403 return JSFunction::cast(GetConstantFromMap(map)); 419 return JSFunction::cast(GetConstantFromMap(map));
404 } 420 }
405 421
406 Object* GetConstant() const { 422 Object* GetConstant() const {
407 ASSERT(type() == CONSTANT); 423 ASSERT(type() == CONSTANT);
408 return GetValue(); 424 return GetValue();
409 } 425 }
410 426
411 Object* GetCallbackObject() const { 427 Object* GetCallbackObject() const {
412 ASSERT(type() == CALLBACKS && !IsTransition()); 428 ASSERT(!IsTransition());
429 ASSERT(type() == CALLBACKS);
413 return GetValue(); 430 return GetValue();
414 } 431 }
415 432
416 #ifdef OBJECT_PRINT 433 #ifdef OBJECT_PRINT
417 void Print(FILE* out); 434 void Print(FILE* out);
418 #endif 435 #endif
419 436
420 Object* GetValue() const { 437 Object* GetValue() const {
421 if (lookup_type_ == DESCRIPTOR_TYPE) { 438 if (lookup_type_ == DESCRIPTOR_TYPE) {
422 return GetValueFromMap(holder()->map()); 439 return GetValueFromMap(holder()->map());
440 } else if (lookup_type_ == TRANSITION_TYPE) {
441 return GetValueFromMap(transition_);
423 } 442 }
424 // In the dictionary case, the data is held in the value field. 443 // In the dictionary case, the data is held in the value field.
425 ASSERT(lookup_type_ == DICTIONARY_TYPE); 444 ASSERT(lookup_type_ == DICTIONARY_TYPE);
426 return holder()->GetNormalizedProperty(this); 445 return holder()->GetNormalizedProperty(this);
427 } 446 }
428 447
429 Object* GetValueFromMap(Map* map) const { 448 Object* GetValueFromMap(Map* map) const {
430 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); 449 ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
450 lookup_type_ == TRANSITION_TYPE);
431 ASSERT(number_ < map->NumberOfOwnDescriptors()); 451 ASSERT(number_ < map->NumberOfOwnDescriptors());
432 return map->instance_descriptors()->GetValue(number_); 452 return map->instance_descriptors()->GetValue(number_);
433 } 453 }
434 454
435 int GetFieldIndexFromMap(Map* map) const { 455 int GetFieldIndexFromMap(Map* map) const {
436 ASSERT(lookup_type_ == DESCRIPTOR_TYPE); 456 ASSERT(lookup_type_ == DESCRIPTOR_TYPE ||
457 lookup_type_ == TRANSITION_TYPE);
437 ASSERT(number_ < map->NumberOfOwnDescriptors()); 458 ASSERT(number_ < map->NumberOfOwnDescriptors());
438 return map->instance_descriptors()->GetFieldIndex(number_); 459 return map->instance_descriptors()->GetFieldIndex(number_);
439 } 460 }
440 461
441 void Iterate(ObjectVisitor* visitor); 462 void Iterate(ObjectVisitor* visitor);
442 463
443 private: 464 private:
444 Isolate* isolate_; 465 Isolate* isolate_;
445 LookupResult* next_; 466 LookupResult* next_;
446 467
(...skipping 10 matching lines...) Expand all
457 JSReceiver* holder_; 478 JSReceiver* holder_;
458 Map* transition_; 479 Map* transition_;
459 int number_; 480 int number_;
460 bool cacheable_; 481 bool cacheable_;
461 PropertyDetails details_; 482 PropertyDetails details_;
462 }; 483 };
463 484
464 } } // namespace v8::internal 485 } } // namespace v8::internal
465 486
466 #endif // V8_PROPERTY_H_ 487 #endif // V8_PROPERTY_H_
OLDNEW
« no previous file with comments | « src/objects-printer.cc ('k') | src/property.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698