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

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

Powered by Google App Engine
This is Rietveld 408576698