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

Side by Side Diff: src/ic/arm/handler-compiler-arm.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 | « no previous file | src/ic/arm64/handler-compiler-arm64.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_ARM 5 #if V8_TARGET_ARCH_ARM
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 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 DCHECK(!value_reg.is(scratch)); 400 DCHECK(!value_reg.is(scratch));
401 __ JumpIfSmi(value_reg, miss_label); 401 __ JumpIfSmi(value_reg, miss_label);
402 if (field_type->IsClass()) { 402 if (field_type->IsClass()) {
403 __ ldr(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 403 __ ldr(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset));
404 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()), 404 __ CmpWeakValue(map_reg, Map::WeakCellForMap(field_type->AsClass()),
405 scratch); 405 scratch);
406 __ b(ne, miss_label); 406 __ b(ne, miss_label);
407 } 407 }
408 } 408 }
409 409
410
411 Register PropertyHandlerCompiler::CheckPrototypes( 410 Register PropertyHandlerCompiler::CheckPrototypes(
412 Register object_reg, Register holder_reg, Register scratch1, 411 Register object_reg, Register holder_reg, Register scratch1,
413 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, 412 Register scratch2, Handle<Name> name, Label* miss,
414 ReturnHolder return_what) { 413 ReturnHolder return_what) {
415 Handle<Map> receiver_map = map(); 414 Handle<Map> receiver_map = map();
416 415
417 // Make sure there's no overlap between holder and object registers. 416 // Make sure there's no overlap between holder and object registers.
418 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 417 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
419 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 418 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
420 !scratch2.is(scratch1)); 419 !scratch2.is(scratch1));
421 420
422 Handle<Cell> validity_cell = 421 Handle<Cell> validity_cell =
423 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 422 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
424 if (!validity_cell.is_null()) { 423 if (!validity_cell.is_null()) {
425 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); 424 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value());
426 __ mov(scratch1, Operand(validity_cell)); 425 __ mov(scratch1, Operand(validity_cell));
427 __ ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); 426 __ ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
428 __ cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid))); 427 __ cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid)));
429 __ b(ne, miss); 428 __ b(ne, miss);
430 } 429 }
431 430
432 // The prototype chain of primitives (and their JSValue wrappers) depends
433 // on the native context, which can't be guarded by validity cells.
434 // |object_reg| holds the native context specific prototype in this case;
435 // we need to check its map.
436 if (check == CHECK_ALL_MAPS) {
437 __ ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
438 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
439 __ CmpWeakValue(scratch1, cell, scratch2);
440 __ b(ne, miss);
441 }
442
443 // Keep track of the current object in register reg. 431 // Keep track of the current object in register reg.
444 Register reg = object_reg; 432 Register reg = object_reg;
445 int depth = 0; 433 int depth = 0;
446 434
447 Handle<JSObject> current = Handle<JSObject>::null(); 435 Handle<JSObject> current = Handle<JSObject>::null();
448 if (receiver_map->IsJSGlobalObjectMap()) { 436 if (receiver_map->IsJSGlobalObjectMap()) {
449 current = isolate()->global_object(); 437 current = isolate()->global_object();
450 } 438 }
451 439
452 Handle<JSObject> prototype = Handle<JSObject>::null(); 440 Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()),
453 Handle<Map> current_map = receiver_map; 441 isolate());
454 Handle<Map> holder_map(holder()->map()); 442 Handle<Map> holder_map(holder()->map());
455 // Traverse the prototype chain and check the maps in the prototype chain for 443 // Traverse the prototype chain and check the maps in the prototype chain for
456 // fast and global objects or do negative lookup for normal objects. 444 // fast and global objects or do negative lookup for normal objects.
457 while (!current_map.is_identical_to(holder_map)) { 445 while (!current_map.is_identical_to(holder_map)) {
458 ++depth; 446 ++depth;
459 447
460 prototype = handle(JSObject::cast(current_map->prototype()));
461 if (current_map->IsJSGlobalObjectMap()) { 448 if (current_map->IsJSGlobalObjectMap()) {
462 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 449 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
463 name, scratch2, miss); 450 name, scratch2, miss);
464 } else if (current_map->is_dictionary_map()) { 451 } else if (current_map->is_dictionary_map()) {
465 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 452 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
466 DCHECK(name->IsUniqueName()); 453 DCHECK(name->IsUniqueName());
467 DCHECK(current.is_null() || 454 DCHECK(current.is_null() ||
468 current->property_dictionary()->FindEntry(name) == 455 current->property_dictionary()->FindEntry(name) ==
469 NameDictionary::kNotFound); 456 NameDictionary::kNotFound);
470 457
471 if (depth > 1) { 458 if (depth > 1) {
472 Handle<WeakCell> weak_cell = 459 Handle<WeakCell> weak_cell =
473 Map::GetOrCreatePrototypeWeakCell(current, isolate()); 460 Map::GetOrCreatePrototypeWeakCell(current, isolate());
474 __ LoadWeakValue(reg, weak_cell, miss); 461 __ LoadWeakValue(reg, weak_cell, miss);
475 } 462 }
476 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 463 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
477 scratch2); 464 scratch2);
478 } 465 }
479 466
480 reg = holder_reg; // From now on the object will be in holder_reg. 467 reg = holder_reg; // From now on the object will be in holder_reg.
481 // Go to the next object in the prototype chain. 468 // Go to the next object in the prototype chain.
482 current = prototype; 469 current = handle(JSObject::cast(current_map->prototype()));
483 current_map = handle(current->map()); 470 current_map = handle(current->map());
484 } 471 }
485 472
486 DCHECK(!current_map->IsJSGlobalProxyMap()); 473 DCHECK(!current_map->IsJSGlobalProxyMap());
487 474
488 // Log the check depth. 475 // Log the check depth.
489 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 476 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
490 477
491 bool return_holder = return_what == RETURN_HOLDER; 478 bool return_holder = return_what == RETURN_HOLDER;
492 if (return_holder && depth != 0) { 479 if (return_holder && depth != 0) {
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 // Return the generated code. 661 // Return the generated code.
675 return GetCode(kind(), name); 662 return GetCode(kind(), name);
676 } 663 }
677 664
678 665
679 #undef __ 666 #undef __
680 } // namespace internal 667 } // namespace internal
681 } // namespace v8 668 } // namespace v8
682 669
683 #endif // V8_TARGET_ARCH_ARM 670 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/ic/arm64/handler-compiler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698