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

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 573003: ia32: Fuse map and type checks in call ICs for API functions. (Closed)
Patch Set: Rewrote a comment. Created 10 years, 10 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
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 void MacroAssembler::PopTryHandler() { 531 void MacroAssembler::PopTryHandler() {
532 ASSERT_EQ(0, StackHandlerConstants::kNextOffset); 532 ASSERT_EQ(0, StackHandlerConstants::kNextOffset);
533 pop(Operand::StaticVariable(ExternalReference(Top::k_handler_address))); 533 pop(Operand::StaticVariable(ExternalReference(Top::k_handler_address)));
534 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); 534 add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize));
535 } 535 }
536 536
537 537
538 Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg, 538 Register MacroAssembler::CheckMaps(JSObject* object, Register object_reg,
539 JSObject* holder, Register holder_reg, 539 JSObject* holder, Register holder_reg,
540 Register scratch, 540 Register scratch,
541 int save_at_depth,
541 Label* miss) { 542 Label* miss) {
542 // Make sure there's no overlap between scratch and the other 543 // Make sure there's no overlap between scratch and the other
543 // registers. 544 // registers.
544 ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg)); 545 ASSERT(!scratch.is(object_reg) && !scratch.is(holder_reg));
545 546
546 // Keep track of the current object in register reg. 547 // Keep track of the current object in register reg.
547 Register reg = object_reg; 548 Register reg = object_reg;
548 int depth = 1; 549 int depth = 0;
550
551 if (save_at_depth == depth) {
552 mov(Operand(esp, kPointerSize), object_reg);
553 }
549 554
550 // Check the maps in the prototype chain. 555 // Check the maps in the prototype chain.
551 // Traverse the prototype chain from the object and do map checks. 556 // Traverse the prototype chain from the object and do map checks.
552 while (object != holder) { 557 while (object != holder) {
553 depth++; 558 depth++;
554 559
555 // Only global objects and objects that do not require access 560 // Only global objects and objects that do not require access
556 // checks are allowed in stubs. 561 // checks are allowed in stubs.
557 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 562 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
558 563
(...skipping 11 matching lines...) Expand all
570 CheckAccessGlobalProxy(reg, scratch, miss); 575 CheckAccessGlobalProxy(reg, scratch, miss);
571 576
572 // Restore scratch register to be the map of the object. 577 // Restore scratch register to be the map of the object.
573 // We load the prototype from the map in the scratch register. 578 // We load the prototype from the map in the scratch register.
574 mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 579 mov(scratch, FieldOperand(reg, HeapObject::kMapOffset));
575 } 580 }
576 // The prototype is in new space; we cannot store a reference 581 // The prototype is in new space; we cannot store a reference
577 // to it in the code. Load it from the map. 582 // to it in the code. Load it from the map.
578 reg = holder_reg; // from now the object is in holder_reg 583 reg = holder_reg; // from now the object is in holder_reg
579 mov(reg, FieldOperand(scratch, Map::kPrototypeOffset)); 584 mov(reg, FieldOperand(scratch, Map::kPrototypeOffset));
580
581 } else { 585 } else {
582 // Check the map of the current object. 586 // Check the map of the current object.
583 cmp(FieldOperand(reg, HeapObject::kMapOffset), 587 cmp(FieldOperand(reg, HeapObject::kMapOffset),
584 Immediate(Handle<Map>(object->map()))); 588 Immediate(Handle<Map>(object->map())));
585 // Branch on the result of the map check. 589 // Branch on the result of the map check.
586 j(not_equal, miss, not_taken); 590 j(not_equal, miss, not_taken);
587 // Check access rights to the global object. This has to happen 591 // Check access rights to the global object. This has to happen
588 // after the map check so that we know that the object is 592 // after the map check so that we know that the object is
589 // actually a global object. 593 // actually a global object.
590 if (object->IsJSGlobalProxy()) { 594 if (object->IsJSGlobalProxy()) {
591 CheckAccessGlobalProxy(reg, scratch, miss); 595 CheckAccessGlobalProxy(reg, scratch, miss);
592 } 596 }
593 // The prototype is in old space; load it directly. 597 // The prototype is in old space; load it directly.
594 reg = holder_reg; // from now the object is in holder_reg 598 reg = holder_reg; // from now the object is in holder_reg
595 mov(reg, Handle<JSObject>(prototype)); 599 mov(reg, Handle<JSObject>(prototype));
596 } 600 }
597 601
602 if (save_at_depth == depth) {
603 mov(Operand(esp, kPointerSize), reg);
604 }
605
598 // Go to the next object in the prototype chain. 606 // Go to the next object in the prototype chain.
599 object = prototype; 607 object = prototype;
600 } 608 }
601 609
602 // Check the holder map. 610 // Check the holder map.
603 cmp(FieldOperand(reg, HeapObject::kMapOffset), 611 cmp(FieldOperand(reg, HeapObject::kMapOffset),
604 Immediate(Handle<Map>(holder->map()))); 612 Immediate(Handle<Map>(holder->map())));
605 j(not_equal, miss, not_taken); 613 j(not_equal, miss, not_taken);
606 614
607 // Log the check depth. 615 // Log the check depth.
608 LOG(IntEvent("check-maps-depth", depth)); 616 LOG(IntEvent("check-maps-depth", depth + 1));
609 617
610 // Perform security check for access to the global object and return 618 // Perform security check for access to the global object and return
611 // the holder register. 619 // the holder register.
612 ASSERT(object == holder); 620 ASSERT(object == holder);
613 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 621 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
614 if (object->IsJSGlobalProxy()) { 622 if (object->IsJSGlobalProxy()) {
615 CheckAccessGlobalProxy(reg, scratch, miss); 623 CheckAccessGlobalProxy(reg, scratch, miss);
616 } 624 }
617 return reg; 625 return reg;
618 } 626 }
(...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 // Indicate that code has changed. 1599 // Indicate that code has changed.
1592 CPU::FlushICache(address_, size_); 1600 CPU::FlushICache(address_, size_);
1593 1601
1594 // Check that the code was patched as expected. 1602 // Check that the code was patched as expected.
1595 ASSERT(masm_.pc_ == address_ + size_); 1603 ASSERT(masm_.pc_ == address_ + size_);
1596 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 1604 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
1597 } 1605 }
1598 1606
1599 1607
1600 } } // namespace v8::internal 1608 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698