OLD | NEW |
---|---|
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 23 matching lines...) Expand all Loading... | |
34 namespace v8 { | 34 namespace v8 { |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
37 #define __ ACCESS_MASM(masm) | 37 #define __ ACCESS_MASM(masm) |
38 | 38 |
39 | 39 |
40 static void ProbeTable(MacroAssembler* masm, | 40 static void ProbeTable(MacroAssembler* masm, |
41 Code::Flags flags, | 41 Code::Flags flags, |
42 StubCache::Table table, | 42 StubCache::Table table, |
43 Register name, | 43 Register name, |
44 Register offset) { | 44 Register offset, |
45 Register extra) { | |
45 ExternalReference key_offset(SCTableReference::keyReference(table)); | 46 ExternalReference key_offset(SCTableReference::keyReference(table)); |
46 ExternalReference value_offset(SCTableReference::valueReference(table)); | 47 ExternalReference value_offset(SCTableReference::valueReference(table)); |
47 | 48 |
48 Label miss; | 49 Label miss; |
49 | 50 |
50 // Save the offset on the stack. | 51 if (extra.is_valid()) { |
51 __ push(offset); | 52 // Get the code entry from the cache. |
Kasper Lund
2009/07/02 12:53:08
I take it you've considered having multiple extra.
| |
53 __ mov(extra, Operand::StaticArray(offset, times_2, value_offset)); | |
52 | 54 |
53 // Check that the key in the entry matches the name. | 55 // Check that the key in the entry matches the name. |
54 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset)); | 56 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset)); |
55 __ j(not_equal, &miss, not_taken); | 57 __ j(not_equal, &miss, not_taken); |
56 | 58 |
57 // Get the code entry from the cache. | 59 // Check that the flags match what we're looking for. |
58 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset)); | 60 __ mov(offset, FieldOperand(extra, Code::kFlagsOffset)); |
61 __ and_(offset, ~Code::kFlagsNotUsedInLookup); | |
62 __ cmp(offset, flags); | |
63 __ j(not_equal, &miss); | |
59 | 64 |
60 // Check that the flags match what we're looking for. | 65 // Jump to the first instruction in the code stub. |
61 __ mov(offset, FieldOperand(offset, Code::kFlagsOffset)); | 66 __ add(Operand(extra), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
62 __ and_(offset, ~Code::kFlagsNotUsedInLookup); | 67 __ jmp(Operand(extra)); |
63 __ cmp(offset, flags); | |
64 __ j(not_equal, &miss); | |
65 | 68 |
66 // Restore offset and re-load code entry from cache. | 69 } else { |
67 __ pop(offset); | 70 // Check that the key in the entry matches the name. |
68 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset)); | 71 __ cmp(name, Operand::StaticArray(offset, times_2, key_offset)); |
72 __ j(not_equal, &miss, not_taken); | |
69 | 73 |
70 // Jump to the first instruction in the code stub. | 74 // Get the code entry from the cache. |
71 __ add(Operand(offset), Immediate(Code::kHeaderSize - kHeapObjectTag)); | 75 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset)); |
72 __ jmp(Operand(offset)); | |
73 | 76 |
74 // Miss: Restore offset and fall through. | 77 // Check that the flags match what we're looking for. |
78 __ mov(offset, FieldOperand(offset, Code::kFlagsOffset)); | |
79 __ and_(offset, ~Code::kFlagsNotUsedInLookup); | |
80 __ cmp(offset, flags); | |
81 __ j(not_equal, &miss); | |
82 | |
83 // Restore offset and re-load code entry from cache. | |
84 __ mov(offset, Operand::StaticArray(offset, times_2, value_offset)); | |
85 | |
86 // Jump to the first instruction in the code stub. | |
87 __ add(Operand(offset), Immediate(Code::kHeaderSize - kHeapObjectTag)); | |
88 __ jmp(Operand(offset)); | |
89 | |
90 } | |
75 __ bind(&miss); | 91 __ bind(&miss); |
76 __ pop(offset); | |
77 } | 92 } |
78 | 93 |
79 | 94 |
80 void StubCache::GenerateProbe(MacroAssembler* masm, | 95 void StubCache::GenerateProbe(MacroAssembler* masm, |
81 Code::Flags flags, | 96 Code::Flags flags, |
82 Register receiver, | 97 Register receiver, |
83 Register name, | 98 Register name, |
84 Register scratch) { | 99 Register scratch, |
100 Register extra) { | |
85 Label miss; | 101 Label miss; |
86 | 102 |
87 // Make sure that code is valid. The shifting code relies on the | 103 // Make sure that code is valid. The shifting code relies on the |
88 // entry size being 8. | 104 // entry size being 8. |
89 ASSERT(sizeof(Entry) == 8); | 105 ASSERT(sizeof(Entry) == 8); |
90 | 106 |
91 // Make sure the flags does not name a specific type. | 107 // Make sure the flags does not name a specific type. |
92 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); | 108 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); |
93 | 109 |
94 // Make sure that there are no register conflicts. | 110 // Make sure that there are no register conflicts. |
95 ASSERT(!scratch.is(receiver)); | 111 ASSERT(!scratch.is(receiver)); |
96 ASSERT(!scratch.is(name)); | 112 ASSERT(!scratch.is(name)); |
97 | 113 |
98 // Check that the receiver isn't a smi. | 114 // Check that the receiver isn't a smi. |
99 __ test(receiver, Immediate(kSmiTagMask)); | 115 __ test(receiver, Immediate(kSmiTagMask)); |
100 __ j(zero, &miss, not_taken); | 116 __ j(zero, &miss, not_taken); |
101 | 117 |
102 // Get the map of the receiver and compute the hash. | 118 // Get the map of the receiver and compute the hash. |
103 __ mov(scratch, FieldOperand(name, String::kLengthOffset)); | 119 __ mov(scratch, FieldOperand(name, String::kLengthOffset)); |
104 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | 120 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); |
105 __ xor_(scratch, flags); | 121 __ xor_(scratch, flags); |
106 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | 122 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); |
107 | 123 |
108 // Probe the primary table. | 124 // Probe the primary table. |
109 ProbeTable(masm, flags, kPrimary, name, scratch); | 125 ProbeTable(masm, flags, kPrimary, name, scratch, extra); |
110 | 126 |
111 // Primary miss: Compute hash for secondary probe. | 127 // Primary miss: Compute hash for secondary probe. |
128 __ mov(scratch, FieldOperand(name, String::kLengthOffset)); | |
129 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); | |
130 __ xor_(scratch, flags); | |
131 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); | |
112 __ sub(scratch, Operand(name)); | 132 __ sub(scratch, Operand(name)); |
113 __ add(Operand(scratch), Immediate(flags)); | 133 __ add(Operand(scratch), Immediate(flags)); |
114 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); | 134 __ and_(scratch, (kSecondaryTableSize - 1) << kHeapObjectTagSize); |
115 | 135 |
116 // Probe the secondary table. | 136 // Probe the secondary table. |
117 ProbeTable(masm, flags, kSecondary, name, scratch); | 137 ProbeTable(masm, flags, kSecondary, name, scratch, extra); |
118 | 138 |
119 // Cache miss: Fall-through and let caller handle the miss by | 139 // Cache miss: Fall-through and let caller handle the miss by |
120 // entering the runtime system. | 140 // entering the runtime system. |
121 __ bind(&miss); | 141 __ bind(&miss); |
122 } | 142 } |
123 | 143 |
124 | 144 |
125 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, | 145 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, |
126 int index, | 146 int index, |
127 Register prototype) { | 147 Register prototype) { |
(...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1333 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1353 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1334 | 1354 |
1335 // Return the generated code. | 1355 // Return the generated code. |
1336 return GetCode(CALLBACKS, name); | 1356 return GetCode(CALLBACKS, name); |
1337 } | 1357 } |
1338 | 1358 |
1339 | 1359 |
1340 #undef __ | 1360 #undef __ |
1341 | 1361 |
1342 } } // namespace v8::internal | 1362 } } // namespace v8::internal |
OLD | NEW |