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

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

Issue 908213002: Use Cells to check prototype chain validity (disabled by default). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix arm64 typo (and rebase, sorry) Created 5 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
« no previous file with comments | « src/ic/mips/handler-compiler-mips.cc ('k') | src/ic/x64/handler-compiler-x64.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 #if V8_TARGET_ARCH_MIPS64 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/ic/call-optimization.h" 9 #include "src/ic/call-optimization.h"
10 #include "src/ic/handler-compiler.h" 10 #include "src/ic/handler-compiler.h"
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 395 }
396 __ Branch(&do_store, eq, map_reg, Operand(scratch)); 396 __ Branch(&do_store, eq, map_reg, Operand(scratch));
397 } 397 }
398 __ bind(&do_store); 398 __ bind(&do_store);
399 } 399 }
400 } 400 }
401 401
402 402
403 Register PropertyHandlerCompiler::CheckPrototypes( 403 Register PropertyHandlerCompiler::CheckPrototypes(
404 Register object_reg, Register holder_reg, Register scratch1, 404 Register object_reg, Register holder_reg, Register scratch1,
405 Register scratch2, Handle<Name> name, Label* miss, 405 Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check,
406 PrototypeCheckType check) { 406 ReturnHolder return_what) {
407 Handle<Map> receiver_map = map(); 407 Handle<Map> receiver_map = map();
408 408
409 // Make sure there's no overlap between holder and object registers. 409 // Make sure there's no overlap between holder and object registers.
410 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 410 DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
411 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 411 DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
412 !scratch2.is(scratch1)); 412 !scratch2.is(scratch1));
413 413
414 if (FLAG_eliminate_prototype_chain_checks) {
415 Handle<Cell> validity_cell =
416 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate());
417 if (!validity_cell.is_null()) {
418 DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid),
419 validity_cell->value());
420 __ li(scratch1, Operand(validity_cell));
421 __ ld(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset));
422 __ Branch(miss, ne, scratch1,
423 Operand(Smi::FromInt(Map::kPrototypeChainValid)));
424 }
425
426 // The prototype chain of primitives (and their JSValue wrappers) depends
427 // on the native context, which can't be guarded by validity cells.
428 // |object_reg| holds the native context specific prototype in this case;
429 // we need to check its map.
430 if (check == CHECK_ALL_MAPS) {
431 __ ld(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset));
432 Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
433 __ GetWeakValue(scratch2, cell);
434 __ Branch(miss, ne, scratch1, Operand(scratch2));
435 }
436 }
437
414 // Keep track of the current object in register reg. 438 // Keep track of the current object in register reg.
415 Register reg = object_reg; 439 Register reg = object_reg;
416 int depth = 0; 440 int depth = 0;
417 441
418 Handle<JSObject> current = Handle<JSObject>::null(); 442 Handle<JSObject> current = Handle<JSObject>::null();
419 if (receiver_map->IsJSGlobalObjectMap()) { 443 if (receiver_map->IsJSGlobalObjectMap()) {
420 current = isolate()->global_object(); 444 current = isolate()->global_object();
421 } 445 }
422 446
423 // Check access rights to the global object. This has to happen after 447 // Check access rights to the global object. This has to happen after
(...skipping 24 matching lines...) Expand all
448 !current_map->IsJSGlobalObjectMap()) { 472 !current_map->IsJSGlobalObjectMap()) {
449 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 473 DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast.
450 if (!name->IsUniqueName()) { 474 if (!name->IsUniqueName()) {
451 DCHECK(name->IsString()); 475 DCHECK(name->IsString());
452 name = factory()->InternalizeString(Handle<String>::cast(name)); 476 name = factory()->InternalizeString(Handle<String>::cast(name));
453 } 477 }
454 DCHECK(current.is_null() || 478 DCHECK(current.is_null() ||
455 current->property_dictionary()->FindEntry(name) == 479 current->property_dictionary()->FindEntry(name) ==
456 NameDictionary::kNotFound); 480 NameDictionary::kNotFound);
457 481
482 if (FLAG_eliminate_prototype_chain_checks && depth > 1) {
483 // TODO(jkummerow): Cache and re-use weak cell.
484 __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
485 }
458 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 486 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
459 scratch2); 487 scratch2);
460 488 if (!FLAG_eliminate_prototype_chain_checks) {
461 __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 489 __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
462 reg = holder_reg; // From now on the object will be in holder_reg. 490 __ ld(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
463 __ ld(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 491 }
464 } else { 492 } else {
465 Register map_reg = scratch1; 493 Register map_reg = scratch1;
466 __ ld(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 494 if (!FLAG_eliminate_prototype_chain_checks) {
467 495 __ ld(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
496 }
468 if (current_map->IsJSGlobalObjectMap()) { 497 if (current_map->IsJSGlobalObjectMap()) {
469 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 498 GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
470 name, scratch2, miss); 499 name, scratch2, miss);
471 } else if (depth != 1 || check == CHECK_ALL_MAPS) { 500 } else if (!FLAG_eliminate_prototype_chain_checks &&
501 (depth != 1 || check == CHECK_ALL_MAPS)) {
472 Handle<WeakCell> cell = Map::WeakCellForMap(current_map); 502 Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
473 __ GetWeakValue(scratch2, cell); 503 __ GetWeakValue(scratch2, cell);
474 __ Branch(miss, ne, scratch2, Operand(map_reg)); 504 __ Branch(miss, ne, scratch2, Operand(map_reg));
475 } 505 }
476 506 if (!FLAG_eliminate_prototype_chain_checks) {
477 reg = holder_reg; // From now on the object will be in holder_reg. 507 __ ld(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
478 508 }
479 __ ld(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
480 } 509 }
481 510
511 reg = holder_reg; // From now on the object will be in holder_reg.
482 // Go to the next object in the prototype chain. 512 // Go to the next object in the prototype chain.
483 current = prototype; 513 current = prototype;
484 current_map = handle(current->map()); 514 current_map = handle(current->map());
485 } 515 }
486 516
487 DCHECK(!current_map->IsJSGlobalProxyMap()); 517 DCHECK(!current_map->IsJSGlobalProxyMap());
488 518
489 // Log the check depth. 519 // Log the check depth.
490 LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 520 LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
491 521
492 if (depth != 0 || check == CHECK_ALL_MAPS) { 522 if (!FLAG_eliminate_prototype_chain_checks &&
523 (depth != 0 || check == CHECK_ALL_MAPS)) {
493 // Check the holder map. 524 // Check the holder map.
494 __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 525 __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
495 Handle<WeakCell> cell = Map::WeakCellForMap(current_map); 526 Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
496 __ GetWeakValue(scratch2, cell); 527 __ GetWeakValue(scratch2, cell);
497 __ Branch(miss, ne, scratch2, Operand(scratch1)); 528 __ Branch(miss, ne, scratch2, Operand(scratch1));
498 } 529 }
499 530
531 bool return_holder = return_what == RETURN_HOLDER;
532 if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) {
533 __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss);
534 }
535
500 // Return the register containing the holder. 536 // Return the register containing the holder.
501 return reg; 537 return return_holder ? reg : no_reg;
502 } 538 }
503 539
504 540
505 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 541 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
506 if (!miss->is_unused()) { 542 if (!miss->is_unused()) {
507 Label success; 543 Label success;
508 __ Branch(&success); 544 __ Branch(&success);
509 __ bind(miss); 545 __ bind(miss);
510 if (IC::ICUseVector(kind())) { 546 if (IC::ICUseVector(kind())) {
511 DCHECK(kind() == Code::LOAD_IC); 547 DCHECK(kind() == Code::LOAD_IC);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 742 }
707 743
708 744
709 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 745 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
710 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 746 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
711 Label miss; 747 Label miss;
712 if (IC::ICUseVector(kind())) { 748 if (IC::ICUseVector(kind())) {
713 PushVectorAndSlot(); 749 PushVectorAndSlot();
714 } 750 }
715 751
716 FrontendHeader(receiver(), name, &miss); 752 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
717 753
718 // Get the value from the cell. 754 // Get the value from the cell.
719 Register result = StoreDescriptor::ValueRegister(); 755 Register result = StoreDescriptor::ValueRegister();
720 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); 756 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
721 __ LoadWeakValue(result, weak_cell, &miss); 757 __ LoadWeakValue(result, weak_cell, &miss);
722 __ ld(result, FieldMemOperand(result, PropertyCell::kValueOffset)); 758 __ ld(result, FieldMemOperand(result, PropertyCell::kValueOffset));
723 759
724 // Check for deleted property if property can actually be deleted. 760 // Check for deleted property if property can actually be deleted.
725 if (is_configurable) { 761 if (is_configurable) {
726 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 762 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
(...skipping 13 matching lines...) Expand all
740 // Return the generated code. 776 // Return the generated code.
741 return GetCode(kind(), Code::NORMAL, name); 777 return GetCode(kind(), Code::NORMAL, name);
742 } 778 }
743 779
744 780
745 #undef __ 781 #undef __
746 } 782 }
747 } // namespace v8::internal 783 } // namespace v8::internal
748 784
749 #endif // V8_TARGET_ARCH_MIPS64 785 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/ic/mips/handler-compiler-mips.cc ('k') | src/ic/x64/handler-compiler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698