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

Side by Side Diff: src/ic/ia32/handler-compiler-ia32.cc

Issue 2466553002: [ic] Simplify handling of primitive maps. (Closed)
Patch Set: Now with enabled data-drived ICs Created 4 years, 1 month 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
« no previous file with comments | « src/ic/handler-compiler.cc ('k') | src/ic/ic.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 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/ic/handler-compiler.h" 7 #include "src/ic/handler-compiler.h"
8 8
9 #include "src/api-arguments.h" 9 #include "src/api-arguments.h"
10 #include "src/field-type.h" 10 #include "src/field-type.h"
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 DCHECK(!value_reg.is(scratch)); 404 DCHECK(!value_reg.is(scratch));
405 __ JumpIfSmi(value_reg, miss_label); 405 __ JumpIfSmi(value_reg, miss_label);
406 if (field_type->IsClass()) { 406 if (field_type->IsClass()) {
407 __ mov(map_reg, FieldOperand(value_reg, HeapObject::kMapOffset)); 407 __ mov(map_reg, FieldOperand(value_reg, HeapObject::kMapOffset));
408 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), 408 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()),
409 scratch); 409 scratch);
410 __ j(not_equal, miss_label); 410 __ j(not_equal, miss_label);
411 } 411 }
412 } 412 }
413 413
414
415 Register PropertyHandlerCompiler::CheckPrototypes( 414 Register PropertyHandlerCompiler::CheckPrototypes(
416 Register object_reg, Register holder_reg, Register scratch1, 415 Register object_reg, Register holder_reg, Register scratch1,
417 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, 416 Register scratch2, Handle<Name> name, Label* miss,
418 ReturnHolder return_what) { 417 ReturnHolder return_what) {
419 Handle<Map> receiver_map = map(); 418 Handle<Map> receiver_map = map();
420 419
421 // Make sure there's no overlap between holder and object registers. 420 // Make sure there's no overlap between holder and object registers.
422 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 421 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
423 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 422 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
424 !scratch2.is(scratch1)); 423 !scratch2.is(scratch1));
425 424
426 Handle<Cell> validity_cell = 425 Handle<Cell> validity_cell =
427 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 426 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
428 if (!validity_cell.is_null()) { 427 if (!validity_cell.is_null()) {
429 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); 428 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
430 // Operand::ForCell(...) points to the cell's payload! 429 // Operand::ForCell(...) points to the cell's payload!
431 __ cmp(Operand::ForCell(validity_cell), 430 __ cmp(Operand::ForCell(validity_cell),
432 Immediate(Smi::FromInt(Map::kPrototypeChainValid))); 431 Immediate(Smi::FromInt(Map::kPrototypeChainValid)));
433 __ j(not_equal, miss); 432 __ j(not_equal, miss);
434 } 433 }
435 434
436 // The prototype chain of primitives (and their JSValue wrappers) depends
437 // on the native context, which can't be guarded by validity cells.
438 // |object_reg| holds the native context specific prototype in this case;
439 // we need to check its map.
440 if (check == CHECK_ALL_MAPS) {
441 __ mov(scratch1, FieldOperand(object_reg, HeapObject::kMapOffset));
442 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
443 __ CmpWeakValue(scratch1, cell, scratch2);
444 __ j(not_equal, miss);
445 }
446
447 // Keep track of the current object in register reg. 435 // Keep track of the current object in register reg.
448 Register reg = object_reg; 436 Register reg = object_reg;
449 int depth = 0; 437 int depth = 0;
450 438
451 Handle<JSObject> current = Handle<JSObject>::null(); 439 Handle<JSObject> current = Handle<JSObject>::null();
452 if (receiver_map->IsJSGlobalObjectMap()) { 440 if (receiver_map->IsJSGlobalObjectMap()) {
453 current = isolate()->global_object(); 441 current = isolate()->global_object();
454 } 442 }
455 443
456 Handle<JSObject> prototype = Handle<JSObject>::null(); 444 Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()),
457 Handle<Map> current_map = receiver_map; 445 isolate());
458 Handle<Map> holder_map(holder()->map()); 446 Handle<Map> holder_map(holder()->map());
459 // Traverse the prototype chain and check the maps in the prototype chain for 447 // Traverse the prototype chain and check the maps in the prototype chain for
460 // fast and global objects or do negative lookup for normal objects. 448 // fast and global objects or do negative lookup for normal objects.
461 while (!current_map.is_identical_to(holder_map)) { 449 while (!current_map.is_identical_to(holder_map)) {
462 ++depth; 450 ++depth;
463 451
464 prototype = handle(JSObject::cast(current_map->prototype()));
465 if (current_map->IsJSGlobalObjectMap()) { 452 if (current_map->IsJSGlobalObjectMap()) {
466 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 453 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
467 name, scratch2, miss); 454 name, scratch2, miss);
468 } else if (current_map->is_dictionary_map()) { 455 } else if (current_map->is_dictionary_map()) {
469 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 456 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
470 DCHECK(name->IsUniqueName()); 457 DCHECK(name->IsUniqueName());
471 DCHECK(current.is_null() || 458 DCHECK(current.is_null() ||
472 current->property_dictionary()->FindEntry(name) == 459 current->property_dictionary()->FindEntry(name) ==
473 NameDictionary::kNotFound); 460 NameDictionary::kNotFound);
474 461
475 if (depth > 1) { 462 if (depth > 1) {
476 Handle<WeakCell> weak_cell = 463 Handle<WeakCell> weak_cell =
477 Map::GetOrCreatePrototypeWeakCell(current, isolate()); 464 Map::GetOrCreatePrototypeWeakCell(current, isolate());
478 __ LoadWeakValue(reg, weak_cell, miss); 465 __ LoadWeakValue(reg, weak_cell, miss);
479 } 466 }
480 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 467 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
481 scratch2); 468 scratch2);
482 } 469 }
483 470
484 reg = holder_reg; // From now on the object will be in holder_reg. 471 reg = holder_reg; // From now on the object will be in holder_reg.
485 // Go to the next object in the prototype chain. 472 // Go to the next object in the prototype chain.
486 current = prototype; 473 current = handle(JSObject::cast(current_map->prototype()));
487 current_map = handle(current->map()); 474 current_map = handle(current->map());
488 } 475 }
489 476
490 DCHECK(!current_map->IsJSGlobalProxyMap()); 477 DCHECK(!current_map->IsJSGlobalProxyMap());
491 478
492 // Log the check depth. 479 // Log the check depth.
493 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 480 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
494 481
495 bool return_holder = return_what == RETURN_HOLDER; 482 bool return_holder = return_what == RETURN_HOLDER;
496 if (return_holder && depth != 0) { 483 if (return_holder && depth != 0) {
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 // Return the generated code. 688 // Return the generated code.
702 return GetCode(kind(), name); 689 return GetCode(kind(), name);
703 } 690 }
704 691
705 692
706 #undef __ 693 #undef __
707 } // namespace internal 694 } // namespace internal
708 } // namespace v8 695 } // namespace v8
709 696
710 #endif // V8_TARGET_ARCH_IA32 697 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ic/handler-compiler.cc ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698