Author: [email protected]
Date: Thu Jul 2 23:34:59 2009
New Revision: 2342
Modified:
branches/bleeding_edge/src/ia32/ic-ia32.cc
branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
branches/bleeding_edge/src/stub-cache.h
Log:
Improved code for megamorphic stub on ia32.
Review URL: http://codereview.chromium.org/150225
Modified: branches/bleeding_edge/src/ia32/ic-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/ic-ia32.cc (original)
+++ branches/bleeding_edge/src/ia32/ic-ia32.cc Thu Jul 2 23:34:59 2009
@@ -437,7 +437,7 @@
// Probe the stub cache.
Code::Flags flags =
Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL,
argc);
- StubCache::GenerateProbe(masm, flags, edx, ecx, ebx);
+ StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, eax);
// If the stub cache probing failed, the receiver might be a value.
// For value objects, we use the map of the prototype objects for
@@ -474,7 +474,7 @@
// Probe the stub cache for the value object.
__ bind(&probe);
- StubCache::GenerateProbe(masm, flags, edx, ecx, ebx);
+ StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg);
// Cache miss: Jump to runtime.
__ bind(&miss);
@@ -648,7 +648,7 @@
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
NOT_IN_LOOP,
MONOMORPHIC);
- StubCache::GenerateProbe(masm, flags, eax, ecx, ebx);
+ StubCache::GenerateProbe(masm, flags, eax, ecx, ebx, edx);
// Cache miss: Jump to runtime.
Generate(masm, ExternalReference(IC_Utility(kLoadIC_Miss)));
@@ -878,7 +878,7 @@
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
NOT_IN_LOOP,
MONOMORPHIC);
- StubCache::GenerateProbe(masm, flags, edx, ecx, ebx);
+ StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg);
// Cache miss: Jump to runtime.
Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
Modified: branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/stub-cache-ia32.cc (original)
+++ branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Jul 2 23:34:59
2009
@@ -41,39 +41,61 @@
Code::Flags flags,
StubCache::Table table,
Register name,
- Register offset) {
+ Register offset,
+ Register extra) {
ExternalReference key_offset(SCTableReference::keyReference(table));
ExternalReference value_offset(SCTableReference::valueReference(table));
Label miss;
- // Save the offset on the stack.
- __ push(offset);
-
- // Check that the key in the entry matches the name.
- __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));
- __ j(not_equal, &miss, not_taken);
-
- // Get the code entry from the cache.
- __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));
-
- // Check that the flags match what we're looking for.
- __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));
- __ and_(offset, ~Code::kFlagsNotUsedInLookup);
- __ cmp(offset, flags);
- __ j(not_equal, &miss);
-
- // Restore offset and re-load code entry from cache.
- __ pop(offset);
- __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));
-
- // Jump to the first instruction in the code stub.
- __ add(Operand(offset), Immediate(Code::kHeaderSize - kHeapObjectTag));
- __ jmp(Operand(offset));
-
- // Miss: Restore offset and fall through.
- __ bind(&miss);
- __ pop(offset);
+ if (extra.is_valid()) {
+ // Get the code entry from the cache.
+ __ mov(extra, Operand::StaticArray(offset, times_2, value_offset));
+
+ // Check that the key in the entry matches the name.
+ __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));
+ __ j(not_equal, &miss, not_taken);
+
+ // Check that the flags match what we're looking for.
+ __ mov(offset, FieldOperand(extra, Code::kFlagsOffset));
+ __ and_(offset, ~Code::kFlagsNotUsedInLookup);
+ __ cmp(offset, flags);
+ __ j(not_equal, &miss);
+
+ // Jump to the first instruction in the code stub.
+ __ add(Operand(extra), Immediate(Code::kHeaderSize - kHeapObjectTag));
+ __ jmp(Operand(extra));
+
+ __ bind(&miss);
+ } else {
+ // Save the offset on the stack.
+ __ push(offset);
+
+ // Check that the key in the entry matches the name.
+ __ cmp(name, Operand::StaticArray(offset, times_2, key_offset));
+ __ j(not_equal, &miss, not_taken);
+
+ // Get the code entry from the cache.
+ __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));
+
+ // Check that the flags match what we're looking for.
+ __ mov(offset, FieldOperand(offset, Code::kFlagsOffset));
+ __ and_(offset, ~Code::kFlagsNotUsedInLookup);
+ __ cmp(offset, flags);
+ __ j(not_equal, &miss);
+
+ // Restore offset and re-load code entry from cache.
+ __ pop(offset);
+ __ mov(offset, Operand::StaticArray(offset, times_2, value_offset));
+
+ // Jump to the first instruction in the code stub.
+ __ add(Operand(offset), Immediate(Code::kHeaderSize - kHeapObjectTag));
+ __ jmp(Operand(offset));
+
+ // Pop at miss.
+ __ bind(&miss);
+ __ pop(offset);
+ }
}
@@ -81,7 +103,8 @@
Code::Flags flags,
Register receiver,
Register name,
- Register scratch) {
+ Register scratch,
+ Register extra) {
Label miss;
// Make sure that code is valid. The shifting code relies on the
@@ -94,6 +117,9 @@
// Make sure that there are no register conflicts.
ASSERT(!scratch.is(receiver));
ASSERT(!scratch.is(name));
+ ASSERT(!extra.is(receiver));
+ ASSERT(!extra.is(name));
+ ASSERT(!extra.is(scratch));
// Check that the receiver isn't a smi.
__ test(receiver, Immediate(kSmiTagMask));
@@ -106,15 +132,19 @@
__ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
// Probe the primary table.
- ProbeTable(masm, flags, kPrimary, name, scratch);
+ ProbeTable(masm, flags, kPrimary, name, scratch, extra);
// Primary miss: Compute hash for secondary probe.
+ __ mov(scratch, FieldOperand(name, String::kLengthOffset));
+ __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
+ __ xor_(scratch, flags);
+ __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
__ sub(scratch, Operand(name));
__ add(Operand(scratch), Immediate(flags));
__ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize);
// Probe the secondary table.
- ProbeTable(masm, flags, kSecondary, name, scratch);
+ ProbeTable(masm, flags, kSecondary, name, scratch, extra);
// Cache miss: Fall-through and let caller handle the miss by
// entering the runtime system.
Modified: branches/bleeding_edge/src/stub-cache.h
==============================================================================
--- branches/bleeding_edge/src/stub-cache.h (original)
+++ branches/bleeding_edge/src/stub-cache.h Thu Jul 2 23:34:59 2009
@@ -197,11 +197,13 @@
static void GenerateMiss(MacroAssembler* masm);
// Generate code for probing the stub cache table.
+ // If extra != no_reg it might be used as am extra scratch register.
static void GenerateProbe(MacroAssembler* masm,
Code::Flags flags,
Register receiver,
Register name,
- Register scratch);
+ Register scratch,
+ Register extra);
enum Table {
kPrimary,
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---