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

Side by Side Diff: src/mips64/stub-cache-mips64.cc

Issue 371923006: Add mips64 port. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/mips64/simulator-mips64.cc ('k') | src/objects.h » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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_MIPS 7 #if V8_TARGET_ARCH_MIPS64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
11 #include "src/stub-cache.h" 11 #include "src/stub-cache.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 #define __ ACCESS_MASM(masm) 16 #define __ ACCESS_MASM(masm)
17 17
18 18
19 static void ProbeTable(Isolate* isolate, 19 static void ProbeTable(Isolate* isolate,
20 MacroAssembler* masm, 20 MacroAssembler* masm,
21 Code::Flags flags, 21 Code::Flags flags,
22 StubCache::Table table, 22 StubCache::Table table,
23 Register receiver, 23 Register receiver,
24 Register name, 24 Register name,
25 // Number of the cache entry, not scaled. 25 // Number of the cache entry, not scaled.
26 Register offset, 26 Register offset,
27 Register scratch, 27 Register scratch,
28 Register scratch2, 28 Register scratch2,
29 Register offset_scratch) { 29 Register offset_scratch) {
30 ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); 30 ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
31 ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); 31 ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
32 ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); 32 ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
33 33
34 uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address()); 34 uint64_t key_off_addr = reinterpret_cast<uint64_t>(key_offset.address());
35 uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address()); 35 uint64_t value_off_addr = reinterpret_cast<uint64_t>(value_offset.address());
36 uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address()); 36 uint64_t map_off_addr = reinterpret_cast<uint64_t>(map_offset.address());
37 37
38 // Check the relative positions of the address fields. 38 // Check the relative positions of the address fields.
39 ASSERT(value_off_addr > key_off_addr); 39 ASSERT(value_off_addr > key_off_addr);
40 ASSERT((value_off_addr - key_off_addr) % 4 == 0); 40 ASSERT((value_off_addr - key_off_addr) % 4 == 0);
41 ASSERT((value_off_addr - key_off_addr) < (256 * 4)); 41 ASSERT((value_off_addr - key_off_addr) < (256 * 4));
42 ASSERT(map_off_addr > key_off_addr); 42 ASSERT(map_off_addr > key_off_addr);
43 ASSERT((map_off_addr - key_off_addr) % 4 == 0); 43 ASSERT((map_off_addr - key_off_addr) % 4 == 0);
44 ASSERT((map_off_addr - key_off_addr) < (256 * 4)); 44 ASSERT((map_off_addr - key_off_addr) < (256 * 4));
45 45
46 Label miss; 46 Label miss;
47 Register base_addr = scratch; 47 Register base_addr = scratch;
48 scratch = no_reg; 48 scratch = no_reg;
49 49
50 // Multiply by 3 because there are 3 fields per entry (name, code, map). 50 // Multiply by 3 because there are 3 fields per entry (name, code, map).
51 __ sll(offset_scratch, offset, 1); 51 __ dsll(offset_scratch, offset, 1);
52 __ Addu(offset_scratch, offset_scratch, offset); 52 __ Daddu(offset_scratch, offset_scratch, offset);
53 53
54 // Calculate the base address of the entry. 54 // Calculate the base address of the entry.
55 __ li(base_addr, Operand(key_offset)); 55 __ li(base_addr, Operand(key_offset));
56 __ sll(at, offset_scratch, kPointerSizeLog2); 56 __ dsll(at, offset_scratch, kPointerSizeLog2);
57 __ Addu(base_addr, base_addr, at); 57 __ Daddu(base_addr, base_addr, at);
58 58
59 // Check that the key in the entry matches the name. 59 // Check that the key in the entry matches the name.
60 __ lw(at, MemOperand(base_addr, 0)); 60 __ ld(at, MemOperand(base_addr, 0));
61 __ Branch(&miss, ne, name, Operand(at)); 61 __ Branch(&miss, ne, name, Operand(at));
62 62
63 // Check the map matches. 63 // Check the map matches.
64 __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr)); 64 __ ld(at, MemOperand(base_addr, map_off_addr - key_off_addr));
65 __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 65 __ ld(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
66 __ Branch(&miss, ne, at, Operand(scratch2)); 66 __ Branch(&miss, ne, at, Operand(scratch2));
67 67
68 // Get the code entry from the cache. 68 // Get the code entry from the cache.
69 Register code = scratch2; 69 Register code = scratch2;
70 scratch2 = no_reg; 70 scratch2 = no_reg;
71 __ lw(code, MemOperand(base_addr, value_off_addr - key_off_addr)); 71 __ ld(code, MemOperand(base_addr, value_off_addr - key_off_addr));
72 72
73 // Check that the flags match what we're looking for. 73 // Check that the flags match what we're looking for.
74 Register flags_reg = base_addr; 74 Register flags_reg = base_addr;
75 base_addr = no_reg; 75 base_addr = no_reg;
76 __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset)); 76 __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
77 __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup)); 77 __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup));
78 __ Branch(&miss, ne, flags_reg, Operand(flags)); 78 __ Branch(&miss, ne, flags_reg, Operand(flags));
79 79
80 #ifdef DEBUG 80 #ifdef DEBUG
81 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { 81 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
82 __ jmp(&miss); 82 __ jmp(&miss);
83 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { 83 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
84 __ jmp(&miss); 84 __ jmp(&miss);
85 } 85 }
86 #endif 86 #endif
87 87
88 // Jump to the first instruction in the code stub. 88 // Jump to the first instruction in the code stub.
89 __ Addu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag)); 89 __ Daddu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag));
90 __ Jump(at); 90 __ Jump(at);
91 91
92 // Miss: fall through. 92 // Miss: fall through.
93 __ bind(&miss); 93 __ bind(&miss);
94 } 94 }
95 95
96 96
97 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, 97 void StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm,
98 Label* miss_label, 98 Label* miss_label,
99 Register receiver, 99 Register receiver,
100 Handle<Name> name, 100 Handle<Name> name,
101 Register scratch0, 101 Register scratch0,
102 Register scratch1) { 102 Register scratch1) {
103 ASSERT(name->IsUniqueName()); 103 ASSERT(name->IsUniqueName());
104 ASSERT(!receiver.is(scratch0)); 104 ASSERT(!receiver.is(scratch0));
105 Counters* counters = masm->isolate()->counters(); 105 Counters* counters = masm->isolate()->counters();
106 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 106 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
107 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 107 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
108 108
109 Label done; 109 Label done;
110 110
111 const int kInterceptorOrAccessCheckNeededMask = 111 const int kInterceptorOrAccessCheckNeededMask =
112 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 112 (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
113 113
114 // Bail out if the receiver has a named interceptor or requires access checks. 114 // Bail out if the receiver has a named interceptor or requires access checks.
115 Register map = scratch1; 115 Register map = scratch1;
116 __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 116 __ ld(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
117 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 117 __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
118 __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 118 __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
119 __ Branch(miss_label, ne, scratch0, Operand(zero_reg)); 119 __ Branch(miss_label, ne, scratch0, Operand(zero_reg));
120 120
121 // Check that receiver is a JSObject. 121 // Check that receiver is a JSObject.
122 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 122 __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
123 __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); 123 __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
124 124
125 // Load properties array. 125 // Load properties array.
126 Register properties = scratch0; 126 Register properties = scratch0;
127 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 127 __ ld(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
128 // Check that the properties array is a dictionary. 128 // Check that the properties array is a dictionary.
129 __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 129 __ ld(map, FieldMemOperand(properties, HeapObject::kMapOffset));
130 Register tmp = properties; 130 Register tmp = properties;
131 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 131 __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
132 __ Branch(miss_label, ne, map, Operand(tmp)); 132 __ Branch(miss_label, ne, map, Operand(tmp));
133 133
134 // Restore the temporarily used register. 134 // Restore the temporarily used register.
135 __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 135 __ ld(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
136 136
137 137
138 NameDictionaryLookupStub::GenerateNegativeLookup(masm, 138 NameDictionaryLookupStub::GenerateNegativeLookup(masm,
139 miss_label, 139 miss_label,
140 &done, 140 &done,
141 receiver, 141 receiver,
142 properties, 142 properties,
143 name, 143 name,
144 scratch1); 144 scratch1);
145 __ bind(&done); 145 __ bind(&done);
146 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 146 __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
147 } 147 }
148 148
149 149
150 void StubCache::GenerateProbe(MacroAssembler* masm, 150 void StubCache::GenerateProbe(MacroAssembler* masm,
151 Code::Flags flags, 151 Code::Flags flags,
152 Register receiver, 152 Register receiver,
153 Register name, 153 Register name,
154 Register scratch, 154 Register scratch,
155 Register extra, 155 Register extra,
156 Register extra2, 156 Register extra2,
157 Register extra3) { 157 Register extra3) {
158 Isolate* isolate = masm->isolate(); 158 Isolate* isolate = masm->isolate();
159 Label miss; 159 Label miss;
160 160
161 // Make sure that code is valid. The multiplying code relies on the 161 // Make sure that code is valid. The multiplying code relies on the
162 // entry size being 12. 162 // entry size being 12.
163 ASSERT(sizeof(Entry) == 12); 163 // ASSERT(sizeof(Entry) == 12);
164 // ASSERT(sizeof(Entry) == 3 * kPointerSize);
164 165
165 // Make sure the flags does not name a specific type. 166 // Make sure the flags does not name a specific type.
166 ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 167 ASSERT(Code::ExtractTypeFromFlags(flags) == 0);
167 168
168 // Make sure that there are no register conflicts. 169 // Make sure that there are no register conflicts.
169 ASSERT(!scratch.is(receiver)); 170 ASSERT(!scratch.is(receiver));
170 ASSERT(!scratch.is(name)); 171 ASSERT(!scratch.is(name));
171 ASSERT(!extra.is(receiver)); 172 ASSERT(!extra.is(receiver));
172 ASSERT(!extra.is(name)); 173 ASSERT(!extra.is(name));
173 ASSERT(!extra.is(scratch)); 174 ASSERT(!extra.is(scratch));
174 ASSERT(!extra2.is(receiver)); 175 ASSERT(!extra2.is(receiver));
175 ASSERT(!extra2.is(name)); 176 ASSERT(!extra2.is(name));
176 ASSERT(!extra2.is(scratch)); 177 ASSERT(!extra2.is(scratch));
177 ASSERT(!extra2.is(extra)); 178 ASSERT(!extra2.is(extra));
178 179
179 // Check register validity. 180 // Check register validity.
180 ASSERT(!scratch.is(no_reg)); 181 ASSERT(!scratch.is(no_reg));
181 ASSERT(!extra.is(no_reg)); 182 ASSERT(!extra.is(no_reg));
182 ASSERT(!extra2.is(no_reg)); 183 ASSERT(!extra2.is(no_reg));
183 ASSERT(!extra3.is(no_reg)); 184 ASSERT(!extra3.is(no_reg));
184 185
185 Counters* counters = masm->isolate()->counters(); 186 Counters* counters = masm->isolate()->counters();
186 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, 187 __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1,
187 extra2, extra3); 188 extra2, extra3);
188 189
189 // Check that the receiver isn't a smi. 190 // Check that the receiver isn't a smi.
190 __ JumpIfSmi(receiver, &miss); 191 __ JumpIfSmi(receiver, &miss);
191 192
192 // Get the map of the receiver and compute the hash. 193 // Get the map of the receiver and compute the hash.
193 __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); 194 __ ld(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
194 __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); 195 __ ld(at, FieldMemOperand(receiver, HeapObject::kMapOffset));
195 __ Addu(scratch, scratch, at); 196 __ Daddu(scratch, scratch, at);
196 uint32_t mask = kPrimaryTableSize - 1; 197 uint64_t mask = kPrimaryTableSize - 1;
197 // We shift out the last two bits because they are not part of the hash and 198 // We shift out the last two bits because they are not part of the hash and
198 // they are always 01 for maps. 199 // they are always 01 for maps.
199 __ srl(scratch, scratch, kHeapObjectTagSize); 200 __ dsrl(scratch, scratch, kHeapObjectTagSize);
200 __ Xor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); 201 __ Xor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask));
201 __ And(scratch, scratch, Operand(mask)); 202 __ And(scratch, scratch, Operand(mask));
202 203
203 // Probe the primary table. 204 // Probe the primary table.
204 ProbeTable(isolate, 205 ProbeTable(isolate,
205 masm, 206 masm,
206 flags, 207 flags,
207 kPrimary, 208 kPrimary,
208 receiver, 209 receiver,
209 name, 210 name,
210 scratch, 211 scratch,
211 extra, 212 extra,
212 extra2, 213 extra2,
213 extra3); 214 extra3);
214 215
215 // Primary miss: Compute hash for secondary probe. 216 // Primary miss: Compute hash for secondary probe.
216 __ srl(at, name, kHeapObjectTagSize); 217 __ dsrl(at, name, kHeapObjectTagSize);
217 __ Subu(scratch, scratch, at); 218 __ Dsubu(scratch, scratch, at);
218 uint32_t mask2 = kSecondaryTableSize - 1; 219 uint64_t mask2 = kSecondaryTableSize - 1;
219 __ Addu(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask2)); 220 __ Daddu(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask2));
220 __ And(scratch, scratch, Operand(mask2)); 221 __ And(scratch, scratch, Operand(mask2));
221 222
222 // Probe the secondary table. 223 // Probe the secondary table.
223 ProbeTable(isolate, 224 ProbeTable(isolate,
224 masm, 225 masm,
225 flags, 226 flags,
226 kSecondary, 227 kSecondary,
227 receiver, 228 receiver,
228 name, 229 name,
229 scratch, 230 scratch,
230 extra, 231 extra,
231 extra2, 232 extra2,
232 extra3); 233 extra3);
233 234
234 // Cache miss: Fall-through and let caller handle the miss by 235 // Cache miss: Fall-through and let caller handle the miss by
235 // entering the runtime system. 236 // entering the runtime system.
236 __ bind(&miss); 237 __ bind(&miss);
237 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, 238 __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1,
238 extra2, extra3); 239 extra2, extra3);
239 } 240 }
240 241
241 242
242 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 243 void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
243 int index, 244 int index,
244 Register prototype) { 245 Register prototype) {
245 // Load the global or builtins object from the current context. 246 // Load the global or builtins object from the current context.
246 __ lw(prototype, 247 __ ld(prototype,
247 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 248 MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
248 // Load the native context from the global or builtins object. 249 // Load the native context from the global or builtins object.
249 __ lw(prototype, 250 __ ld(prototype,
250 FieldMemOperand(prototype, GlobalObject::kNativeContextOffset)); 251 FieldMemOperand(prototype, GlobalObject::kNativeContextOffset));
251 // Load the function from the native context. 252 // Load the function from the native context.
252 __ lw(prototype, MemOperand(prototype, Context::SlotOffset(index))); 253 __ ld(prototype, MemOperand(prototype, Context::SlotOffset(index)));
253 // Load the initial map. The global functions all have initial maps. 254 // Load the initial map. The global functions all have initial maps.
254 __ lw(prototype, 255 __ ld(prototype,
255 FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); 256 FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset));
256 // Load the prototype from the initial map. 257 // Load the prototype from the initial map.
257 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 258 __ ld(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
258 } 259 }
259 260
260 261
261 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 262 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
262 MacroAssembler* masm, 263 MacroAssembler* masm,
263 int index, 264 int index,
264 Register prototype, 265 Register prototype,
265 Label* miss) { 266 Label* miss) {
266 Isolate* isolate = masm->isolate(); 267 Isolate* isolate = masm->isolate();
267 // Get the global function with the given index. 268 // Get the global function with the given index.
268 Handle<JSFunction> function( 269 Handle<JSFunction> function(
269 JSFunction::cast(isolate->native_context()->get(index))); 270 JSFunction::cast(isolate->native_context()->get(index)));
270 271
271 // Check we're still in the same context. 272 // Check we're still in the same context.
272 Register scratch = prototype; 273 Register scratch = prototype;
273 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 274 const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
274 __ lw(scratch, MemOperand(cp, offset)); 275 __ ld(scratch, MemOperand(cp, offset));
275 __ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 276 __ ld(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
276 __ lw(scratch, MemOperand(scratch, Context::SlotOffset(index))); 277 __ ld(scratch, MemOperand(scratch, Context::SlotOffset(index)));
277 __ li(at, function); 278 __ li(at, function);
278 __ Branch(miss, ne, at, Operand(scratch)); 279 __ Branch(miss, ne, at, Operand(scratch));
279 280
280 // Load its initial map. The global functions all have initial maps. 281 // Load its initial map. The global functions all have initial maps.
281 __ li(prototype, Handle<Map>(function->initial_map())); 282 __ li(prototype, Handle<Map>(function->initial_map()));
282 // Load the prototype from the initial map. 283 // Load the prototype from the initial map.
283 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 284 __ ld(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
284 } 285 }
285 286
286 287
287 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 288 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
288 Register dst, 289 Register dst,
289 Register src, 290 Register src,
290 bool inobject, 291 bool inobject,
291 int index, 292 int index,
292 Representation representation) { 293 Representation representation) {
293 ASSERT(!representation.IsDouble()); 294 ASSERT(!representation.IsDouble());
294 int offset = index * kPointerSize; 295 int offset = index * kPointerSize;
295 if (!inobject) { 296 if (!inobject) {
296 // Calculate the offset into the properties array. 297 // Calculate the offset into the properties array.
297 offset = offset + FixedArray::kHeaderSize; 298 offset = offset + FixedArray::kHeaderSize;
298 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 299 __ ld(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
299 src = dst; 300 src = dst;
300 } 301 }
301 __ lw(dst, FieldMemOperand(src, offset)); 302 __ ld(dst, FieldMemOperand(src, offset));
302 } 303 }
303 304
304 305
305 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 306 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
306 Register receiver, 307 Register receiver,
307 Register scratch, 308 Register scratch,
308 Label* miss_label) { 309 Label* miss_label) {
309 // Check that the receiver isn't a smi. 310 // Check that the receiver isn't a smi.
310 __ JumpIfSmi(receiver, miss_label); 311 __ JumpIfSmi(receiver, miss_label);
311 312
312 // Check that the object is a JS array. 313 // Check that the object is a JS array.
313 __ GetObjectType(receiver, scratch, scratch); 314 __ GetObjectType(receiver, scratch, scratch);
314 __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE)); 315 __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE));
315 316
316 // Load length directly from the JS array. 317 // Load length directly from the JS array.
317 __ Ret(USE_DELAY_SLOT); 318 __ Ret(USE_DELAY_SLOT);
318 __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 319 __ ld(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
319 } 320 }
320 321
321 322
322 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 323 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
323 Register receiver, 324 Register receiver,
324 Register scratch1, 325 Register scratch1,
325 Register scratch2, 326 Register scratch2,
326 Label* miss_label) { 327 Label* miss_label) {
327 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 328 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
328 __ Ret(USE_DELAY_SLOT); 329 __ Ret(USE_DELAY_SLOT);
329 __ mov(v0, scratch1); 330 __ mov(v0, scratch1);
330 } 331 }
331 332
332 333
333 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, 334 void StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm,
334 Handle<JSGlobalObject> global, 335 Handle<JSGlobalObject> global,
335 Handle<Name> name, 336 Handle<Name> name,
336 Register scratch, 337 Register scratch,
337 Label* miss) { 338 Label* miss) {
338 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 339 Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
339 ASSERT(cell->value()->IsTheHole()); 340 ASSERT(cell->value()->IsTheHole());
340 __ li(scratch, Operand(cell)); 341 __ li(scratch, Operand(cell));
341 __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 342 __ ld(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
342 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 343 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
343 __ Branch(miss, ne, scratch, Operand(at)); 344 __ Branch(miss, ne, scratch, Operand(at));
344 } 345 }
345 346
346 347
347 void StoreStubCompiler::GenerateNegativeHolderLookup( 348 void StoreStubCompiler::GenerateNegativeHolderLookup(
348 MacroAssembler* masm, 349 MacroAssembler* masm,
349 Handle<JSObject> holder, 350 Handle<JSObject> holder,
350 Register holder_reg, 351 Register holder_reg,
351 Handle<Name> name, 352 Handle<Name> name,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 __ li(scratch1, constant); 391 __ li(scratch1, constant);
391 __ Branch(miss_label, ne, value_reg, Operand(scratch1)); 392 __ Branch(miss_label, ne, value_reg, Operand(scratch1));
392 } else if (representation.IsSmi()) { 393 } else if (representation.IsSmi()) {
393 __ JumpIfNotSmi(value_reg, miss_label); 394 __ JumpIfNotSmi(value_reg, miss_label);
394 } else if (representation.IsHeapObject()) { 395 } else if (representation.IsHeapObject()) {
395 __ JumpIfSmi(value_reg, miss_label); 396 __ JumpIfSmi(value_reg, miss_label);
396 HeapType* field_type = descriptors->GetFieldType(descriptor); 397 HeapType* field_type = descriptors->GetFieldType(descriptor);
397 HeapType::Iterator<Map> it = field_type->Classes(); 398 HeapType::Iterator<Map> it = field_type->Classes();
398 Handle<Map> current; 399 Handle<Map> current;
399 if (!it.Done()) { 400 if (!it.Done()) {
400 __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 401 __ ld(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
401 Label do_store; 402 Label do_store;
402 while (true) { 403 while (true) {
403 // Do the CompareMap() directly within the Branch() functions. 404 // Do the CompareMap() directly within the Branch() functions.
404 current = it.Current(); 405 current = it.Current();
405 it.Advance(); 406 it.Advance();
406 if (it.Done()) { 407 if (it.Done()) {
407 __ Branch(miss_label, ne, scratch1, Operand(current)); 408 __ Branch(miss_label, ne, scratch1, Operand(current));
408 break; 409 break;
409 } 410 }
410 __ Branch(&do_store, eq, scratch1, Operand(current)); 411 __ Branch(&do_store, eq, scratch1, Operand(current));
411 } 412 }
412 __ bind(&do_store); 413 __ bind(&do_store);
413 } 414 }
414 } else if (representation.IsDouble()) { 415 } else if (representation.IsDouble()) {
415 Label do_store, heap_number; 416 Label do_store, heap_number;
416 __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex); 417 __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
417 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow, 418 __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow);
418 TAG_RESULT, MUTABLE);
419 419
420 __ JumpIfNotSmi(value_reg, &heap_number); 420 __ JumpIfNotSmi(value_reg, &heap_number);
421 __ SmiUntag(scratch1, value_reg); 421 __ SmiUntag(scratch1, value_reg);
422 __ mtc1(scratch1, f6); 422 __ mtc1(scratch1, f6);
423 __ cvt_d_w(f4, f6); 423 __ cvt_d_w(f4, f6);
424 __ jmp(&do_store); 424 __ jmp(&do_store);
425 425
426 __ bind(&heap_number); 426 __ bind(&heap_number);
427 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 427 __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex,
428 miss_label, DONT_DO_SMI_CHECK); 428 miss_label, DONT_DO_SMI_CHECK);
(...skipping 17 matching lines...) Expand all
446 __ Push(a2, a0); 446 __ Push(a2, a0);
447 __ TailCallExternalReference( 447 __ TailCallExternalReference(
448 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 448 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
449 masm->isolate()), 449 masm->isolate()),
450 3, 1); 450 3, 1);
451 return; 451 return;
452 } 452 }
453 453
454 // Update the map of the object. 454 // Update the map of the object.
455 __ li(scratch1, Operand(transition)); 455 __ li(scratch1, Operand(transition));
456 __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 456 __ sd(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
457 457
458 // Update the write barrier for the map field. 458 // Update the write barrier for the map field.
459 __ RecordWriteField(receiver_reg, 459 __ RecordWriteField(receiver_reg,
460 HeapObject::kMapOffset, 460 HeapObject::kMapOffset,
461 scratch1, 461 scratch1,
462 scratch2, 462 scratch2,
463 kRAHasNotBeenSaved, 463 kRAHasNotBeenSaved,
464 kDontSaveFPRegs, 464 kDontSaveFPRegs,
465 OMIT_REMEMBERED_SET, 465 OMIT_REMEMBERED_SET,
466 OMIT_SMI_CHECK); 466 OMIT_SMI_CHECK);
(...skipping 13 matching lines...) Expand all
480 // object and the number of in-object properties is not going to change. 480 // object and the number of in-object properties is not going to change.
481 index -= object->map()->inobject_properties(); 481 index -= object->map()->inobject_properties();
482 482
483 // TODO(verwaest): Share this code as a code stub. 483 // TODO(verwaest): Share this code as a code stub.
484 SmiCheck smi_check = representation.IsTagged() 484 SmiCheck smi_check = representation.IsTagged()
485 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 485 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
486 if (index < 0) { 486 if (index < 0) {
487 // Set the property straight into the object. 487 // Set the property straight into the object.
488 int offset = object->map()->instance_size() + (index * kPointerSize); 488 int offset = object->map()->instance_size() + (index * kPointerSize);
489 if (representation.IsDouble()) { 489 if (representation.IsDouble()) {
490 __ sw(storage_reg, FieldMemOperand(receiver_reg, offset)); 490 __ sd(storage_reg, FieldMemOperand(receiver_reg, offset));
491 } else { 491 } else {
492 __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); 492 __ sd(value_reg, FieldMemOperand(receiver_reg, offset));
493 } 493 }
494 494
495 if (!representation.IsSmi()) { 495 if (!representation.IsSmi()) {
496 // Update the write barrier for the array address. 496 // Update the write barrier for the array address.
497 if (!representation.IsDouble()) { 497 if (!representation.IsDouble()) {
498 __ mov(storage_reg, value_reg); 498 __ mov(storage_reg, value_reg);
499 } 499 }
500 __ RecordWriteField(receiver_reg, 500 __ RecordWriteField(receiver_reg,
501 offset, 501 offset,
502 storage_reg, 502 storage_reg,
503 scratch1, 503 scratch1,
504 kRAHasNotBeenSaved, 504 kRAHasNotBeenSaved,
505 kDontSaveFPRegs, 505 kDontSaveFPRegs,
506 EMIT_REMEMBERED_SET, 506 EMIT_REMEMBERED_SET,
507 smi_check); 507 smi_check);
508 } 508 }
509 } else { 509 } else {
510 // Write to the properties array. 510 // Write to the properties array.
511 int offset = index * kPointerSize + FixedArray::kHeaderSize; 511 int offset = index * kPointerSize + FixedArray::kHeaderSize;
512 // Get the properties array 512 // Get the properties array
513 __ lw(scratch1, 513 __ ld(scratch1,
514 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 514 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
515 if (representation.IsDouble()) { 515 if (representation.IsDouble()) {
516 __ sw(storage_reg, FieldMemOperand(scratch1, offset)); 516 __ sd(storage_reg, FieldMemOperand(scratch1, offset));
517 } else { 517 } else {
518 __ sw(value_reg, FieldMemOperand(scratch1, offset)); 518 __ sd(value_reg, FieldMemOperand(scratch1, offset));
519 } 519 }
520 520
521 if (!representation.IsSmi()) { 521 if (!representation.IsSmi()) {
522 // Update the write barrier for the array address. 522 // Update the write barrier for the array address.
523 if (!representation.IsDouble()) { 523 if (!representation.IsDouble()) {
524 __ mov(storage_reg, value_reg); 524 __ mov(storage_reg, value_reg);
525 } 525 }
526 __ RecordWriteField(scratch1, 526 __ RecordWriteField(scratch1,
527 offset, 527 offset,
528 storage_reg, 528 storage_reg,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 566
567 Representation representation = lookup->representation(); 567 Representation representation = lookup->representation();
568 ASSERT(!representation.IsNone()); 568 ASSERT(!representation.IsNone());
569 if (representation.IsSmi()) { 569 if (representation.IsSmi()) {
570 __ JumpIfNotSmi(value_reg, miss_label); 570 __ JumpIfNotSmi(value_reg, miss_label);
571 } else if (representation.IsHeapObject()) { 571 } else if (representation.IsHeapObject()) {
572 __ JumpIfSmi(value_reg, miss_label); 572 __ JumpIfSmi(value_reg, miss_label);
573 HeapType* field_type = lookup->GetFieldType(); 573 HeapType* field_type = lookup->GetFieldType();
574 HeapType::Iterator<Map> it = field_type->Classes(); 574 HeapType::Iterator<Map> it = field_type->Classes();
575 if (!it.Done()) { 575 if (!it.Done()) {
576 __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 576 __ ld(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
577 Label do_store; 577 Label do_store;
578 Handle<Map> current; 578 Handle<Map> current;
579 while (true) { 579 while (true) {
580 // Do the CompareMap() directly within the Branch() functions. 580 // Do the CompareMap() directly within the Branch() functions.
581 current = it.Current(); 581 current = it.Current();
582 it.Advance(); 582 it.Advance();
583 if (it.Done()) { 583 if (it.Done()) {
584 __ Branch(miss_label, ne, scratch1, Operand(current)); 584 __ Branch(miss_label, ne, scratch1, Operand(current));
585 break; 585 break;
586 } 586 }
587 __ Branch(&do_store, eq, scratch1, Operand(current)); 587 __ Branch(&do_store, eq, scratch1, Operand(current));
588 } 588 }
589 __ bind(&do_store); 589 __ bind(&do_store);
590 } 590 }
591 } else if (representation.IsDouble()) { 591 } else if (representation.IsDouble()) {
592 // Load the double storage. 592 // Load the double storage.
593 if (index.is_inobject()) { 593 if (index.is_inobject()) {
594 __ lw(scratch1, FieldMemOperand(receiver_reg, index.offset())); 594 __ ld(scratch1, FieldMemOperand(receiver_reg, index.offset()));
595 } else { 595 } else {
596 __ lw(scratch1, 596 __ ld(scratch1,
597 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 597 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
598 __ lw(scratch1, FieldMemOperand(scratch1, index.offset())); 598 __ ld(scratch1, FieldMemOperand(scratch1, index.offset()));
599 } 599 }
600 600
601 // Store the value into the storage. 601 // Store the value into the storage.
602 Label do_store, heap_number; 602 Label do_store, heap_number;
603 __ JumpIfNotSmi(value_reg, &heap_number); 603 __ JumpIfNotSmi(value_reg, &heap_number);
604 __ SmiUntag(scratch2, value_reg); 604 __ SmiUntag(scratch2, value_reg);
605 __ mtc1(scratch2, f6); 605 __ mtc1(scratch2, f6);
606 __ cvt_d_w(f4, f6); 606 __ cvt_d_w(f4, f6);
607 __ jmp(&do_store); 607 __ jmp(&do_store);
608 608
609 __ bind(&heap_number); 609 __ bind(&heap_number);
610 __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, 610 __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex,
611 miss_label, DONT_DO_SMI_CHECK); 611 miss_label, DONT_DO_SMI_CHECK);
612 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 612 __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
613 613
614 __ bind(&do_store); 614 __ bind(&do_store);
615 __ sdc1(f4, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); 615 __ sdc1(f4, FieldMemOperand(scratch1, HeapNumber::kValueOffset));
616 // Return the value (register v0). 616 // Return the value (register v0).
617 ASSERT(value_reg.is(a0)); 617 ASSERT(value_reg.is(a0));
618 __ Ret(USE_DELAY_SLOT); 618 __ Ret(USE_DELAY_SLOT);
619 __ mov(v0, a0); 619 __ mov(v0, a0);
620 return; 620 return;
621 } 621 }
622 622
623 // TODO(verwaest): Share this code as a code stub. 623 // TODO(verwaest): Share this code as a code stub.
624 SmiCheck smi_check = representation.IsTagged() 624 SmiCheck smi_check = representation.IsTagged()
625 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 625 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
626 if (index.is_inobject()) { 626 if (index.is_inobject()) {
627 // Set the property straight into the object. 627 // Set the property straight into the object.
628 __ sw(value_reg, FieldMemOperand(receiver_reg, index.offset())); 628 __ sd(value_reg, FieldMemOperand(receiver_reg, index.offset()));
629 629
630 if (!representation.IsSmi()) { 630 if (!representation.IsSmi()) {
631 // Skip updating write barrier if storing a smi. 631 // Skip updating write barrier if storing a smi.
632 __ JumpIfSmi(value_reg, &exit); 632 __ JumpIfSmi(value_reg, &exit);
633 633
634 // Update the write barrier for the array address. 634 // Update the write barrier for the array address.
635 // Pass the now unused name_reg as a scratch register. 635 // Pass the now unused name_reg as a scratch register.
636 __ mov(name_reg, value_reg); 636 __ mov(name_reg, value_reg);
637 __ RecordWriteField(receiver_reg, 637 __ RecordWriteField(receiver_reg,
638 index.offset(), 638 index.offset(),
639 name_reg, 639 name_reg,
640 scratch1, 640 scratch1,
641 kRAHasNotBeenSaved, 641 kRAHasNotBeenSaved,
642 kDontSaveFPRegs, 642 kDontSaveFPRegs,
643 EMIT_REMEMBERED_SET, 643 EMIT_REMEMBERED_SET,
644 smi_check); 644 smi_check);
645 } 645 }
646 } else { 646 } else {
647 // Write to the properties array. 647 // Write to the properties array.
648 // Get the properties array. 648 // Get the properties array.
649 __ lw(scratch1, 649 __ ld(scratch1,
650 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 650 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
651 __ sw(value_reg, FieldMemOperand(scratch1, index.offset())); 651 __ sd(value_reg, FieldMemOperand(scratch1, index.offset()));
652 652
653 if (!representation.IsSmi()) { 653 if (!representation.IsSmi()) {
654 // Skip updating write barrier if storing a smi. 654 // Skip updating write barrier if storing a smi.
655 __ JumpIfSmi(value_reg, &exit); 655 __ JumpIfSmi(value_reg, &exit);
656 656
657 // Update the write barrier for the array address. 657 // Update the write barrier for the array address.
658 // Ok to clobber receiver_reg and name_reg, since we return. 658 // Ok to clobber receiver_reg and name_reg, since we return.
659 __ mov(name_reg, value_reg); 659 __ mov(name_reg, value_reg);
660 __ RecordWriteField(scratch1, 660 __ RecordWriteField(scratch1,
661 index.offset(), 661 index.offset(),
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm, 723 void StubCompiler::GenerateFastApiCall(MacroAssembler* masm,
724 const CallOptimization& optimization, 724 const CallOptimization& optimization,
725 Handle<Map> receiver_map, 725 Handle<Map> receiver_map,
726 Register receiver, 726 Register receiver,
727 Register scratch_in, 727 Register scratch_in,
728 bool is_store, 728 bool is_store,
729 int argc, 729 int argc,
730 Register* values) { 730 Register* values) {
731 ASSERT(!receiver.is(scratch_in)); 731 ASSERT(!receiver.is(scratch_in));
732 // Preparing to push, adjust sp. 732 // Preparing to push, adjust sp.
733 __ Subu(sp, sp, Operand((argc + 1) * kPointerSize)); 733 __ Dsubu(sp, sp, Operand((argc + 1) * kPointerSize));
734 __ sw(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver. 734 __ sd(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver.
735 // Write the arguments to stack frame. 735 // Write the arguments to stack frame.
736 for (int i = 0; i < argc; i++) { 736 for (int i = 0; i < argc; i++) {
737 Register arg = values[argc-1-i]; 737 Register arg = values[argc-1-i];
738 ASSERT(!receiver.is(arg)); 738 ASSERT(!receiver.is(arg));
739 ASSERT(!scratch_in.is(arg)); 739 ASSERT(!scratch_in.is(arg));
740 __ sw(arg, MemOperand(sp, (argc-1-i) * kPointerSize)); // Push arg. 740 __ sd(arg, MemOperand(sp, (argc-1-i) * kPointerSize)); // Push arg.
741 } 741 }
742 ASSERT(optimization.is_simple_api_call()); 742 ASSERT(optimization.is_simple_api_call());
743 743
744 // Abi for CallApiFunctionStub. 744 // Abi for CallApiFunctionStub.
745 Register callee = a0; 745 Register callee = a0;
746 Register call_data = t0; 746 Register call_data = a4;
747 Register holder = a2; 747 Register holder = a2;
748 Register api_function_address = a1; 748 Register api_function_address = a1;
749 749
750 // Put holder in place. 750 // Put holder in place.
751 CallOptimization::HolderLookup holder_lookup; 751 CallOptimization::HolderLookup holder_lookup;
752 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 752 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
753 receiver_map, 753 receiver_map,
754 &holder_lookup); 754 &holder_lookup);
755 switch (holder_lookup) { 755 switch (holder_lookup) {
756 case CallOptimization::kHolderIsReceiver: 756 case CallOptimization::kHolderIsReceiver:
(...skipping 12 matching lines...) Expand all
769 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 769 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
770 Handle<Object> call_data_obj(api_call_info->data(), isolate); 770 Handle<Object> call_data_obj(api_call_info->data(), isolate);
771 771
772 // Put callee in place. 772 // Put callee in place.
773 __ li(callee, function); 773 __ li(callee, function);
774 774
775 bool call_data_undefined = false; 775 bool call_data_undefined = false;
776 // Put call_data in place. 776 // Put call_data in place.
777 if (isolate->heap()->InNewSpace(*call_data_obj)) { 777 if (isolate->heap()->InNewSpace(*call_data_obj)) {
778 __ li(call_data, api_call_info); 778 __ li(call_data, api_call_info);
779 __ lw(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); 779 __ ld(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
780 } else if (call_data_obj->IsUndefined()) { 780 } else if (call_data_obj->IsUndefined()) {
781 call_data_undefined = true; 781 call_data_undefined = true;
782 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); 782 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
783 } else { 783 } else {
784 __ li(call_data, call_data_obj); 784 __ li(call_data, call_data_obj);
785 } 785 }
786 // Put api_function_address in place. 786 // Put api_function_address in place.
787 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 787 Address function_address = v8::ToCData<Address>(api_call_info->callback());
788 ApiFunction fun(function_address); 788 ApiFunction fun(function_address);
789 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 789 ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 ASSERT(name->IsString()); 853 ASSERT(name->IsString());
854 name = factory()->InternalizeString(Handle<String>::cast(name)); 854 name = factory()->InternalizeString(Handle<String>::cast(name));
855 } 855 }
856 ASSERT(current.is_null() || 856 ASSERT(current.is_null() ||
857 current->property_dictionary()->FindEntry(name) == 857 current->property_dictionary()->FindEntry(name) ==
858 NameDictionary::kNotFound); 858 NameDictionary::kNotFound);
859 859
860 GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 860 GenerateDictionaryNegativeLookup(masm(), miss, reg, name,
861 scratch1, scratch2); 861 scratch1, scratch2);
862 862
863 __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 863 __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
864 reg = holder_reg; // From now on the object will be in holder_reg. 864 reg = holder_reg; // From now on the object will be in holder_reg.
865 __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 865 __ ld(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
866 } else { 866 } else {
867 Register map_reg = scratch1; 867 Register map_reg = scratch1;
868 if (depth != 1 || check == CHECK_ALL_MAPS) { 868 if (depth != 1 || check == CHECK_ALL_MAPS) {
869 // CheckMap implicitly loads the map of |reg| into |map_reg|. 869 // CheckMap implicitly loads the map of |reg| into |map_reg|.
870 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 870 __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
871 } else { 871 } else {
872 __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 872 __ ld(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
873 } 873 }
874 874
875 // Check access rights to the global object. This has to happen after 875 // Check access rights to the global object. This has to happen after
876 // the map check so that we know that the object is actually a global 876 // the map check so that we know that the object is actually a global
877 // object. 877 // object.
878 if (current_map->IsJSGlobalProxyMap()) { 878 if (current_map->IsJSGlobalProxyMap()) {
879 __ CheckAccessGlobalProxy(reg, scratch2, miss); 879 __ CheckAccessGlobalProxy(reg, scratch2, miss);
880 } else if (current_map->IsJSGlobalObjectMap()) { 880 } else if (current_map->IsJSGlobalObjectMap()) {
881 GenerateCheckPropertyCell( 881 GenerateCheckPropertyCell(
882 masm(), Handle<JSGlobalObject>::cast(current), name, 882 masm(), Handle<JSGlobalObject>::cast(current), name,
883 scratch2, miss); 883 scratch2, miss);
884 } 884 }
885 885
886 reg = holder_reg; // From now on the object will be in holder_reg. 886 reg = holder_reg; // From now on the object will be in holder_reg.
887 887
888 if (heap()->InNewSpace(*prototype)) { 888 if (heap()->InNewSpace(*prototype)) {
889 // The prototype is in new space; we cannot store a reference to it 889 // The prototype is in new space; we cannot store a reference to it
890 // in the code. Load it from the map. 890 // in the code. Load it from the map.
891 __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 891 __ ld(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
892 } else { 892 } else {
893 // The prototype is in old space; load it directly. 893 // The prototype is in old space; load it directly.
894 __ li(reg, Operand(prototype)); 894 __ li(reg, Operand(prototype));
895 } 895 }
896 } 896 }
897 897
898 // Go to the next object in the prototype chain. 898 // Go to the next object in the prototype chain.
899 current = prototype; 899 current = prototype;
900 current_map = handle(current->map()); 900 current_map = handle(current->map());
901 } 901 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 952
953 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 953 Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss);
954 954
955 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 955 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
956 ASSERT(!reg.is(scratch2())); 956 ASSERT(!reg.is(scratch2()));
957 ASSERT(!reg.is(scratch3())); 957 ASSERT(!reg.is(scratch3()));
958 ASSERT(!reg.is(scratch4())); 958 ASSERT(!reg.is(scratch4()));
959 959
960 // Load the properties dictionary. 960 // Load the properties dictionary.
961 Register dictionary = scratch4(); 961 Register dictionary = scratch4();
962 __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 962 __ ld(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset));
963 963
964 // Probe the dictionary. 964 // Probe the dictionary.
965 Label probe_done; 965 Label probe_done;
966 NameDictionaryLookupStub::GeneratePositiveLookup(masm(), 966 NameDictionaryLookupStub::GeneratePositiveLookup(masm(),
967 &miss, 967 &miss,
968 &probe_done, 968 &probe_done,
969 dictionary, 969 dictionary,
970 this->name(), 970 this->name(),
971 scratch2(), 971 scratch2(),
972 scratch3()); 972 scratch3());
973 __ bind(&probe_done); 973 __ bind(&probe_done);
974 974
975 // If probing finds an entry in the dictionary, scratch3 contains the 975 // If probing finds an entry in the dictionary, scratch3 contains the
976 // pointer into the dictionary. Check that the value is the callback. 976 // pointer into the dictionary. Check that the value is the callback.
977 Register pointer = scratch3(); 977 Register pointer = scratch3();
978 const int kElementsStartOffset = NameDictionary::kHeaderSize + 978 const int kElementsStartOffset = NameDictionary::kHeaderSize +
979 NameDictionary::kElementsStartIndex * kPointerSize; 979 NameDictionary::kElementsStartIndex * kPointerSize;
980 const int kValueOffset = kElementsStartOffset + kPointerSize; 980 const int kValueOffset = kElementsStartOffset + kPointerSize;
981 __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); 981 __ ld(scratch2(), FieldMemOperand(pointer, kValueOffset));
982 __ Branch(&miss, ne, scratch2(), Operand(callback)); 982 __ Branch(&miss, ne, scratch2(), Operand(callback));
983 } 983 }
984 984
985 HandlerFrontendFooter(name, &miss); 985 HandlerFrontendFooter(name, &miss);
986 return reg; 986 return reg;
987 } 987 }
988 988
989 989
990 void LoadStubCompiler::GenerateLoadField(Register reg, 990 void LoadStubCompiler::GenerateLoadField(Register reg,
991 Handle<JSObject> holder, 991 Handle<JSObject> holder,
(...skipping 28 matching lines...) Expand all
1020 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 1020 STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
1021 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 1021 STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
1022 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 1022 STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
1023 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 1023 STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
1024 ASSERT(!scratch2().is(reg)); 1024 ASSERT(!scratch2().is(reg));
1025 ASSERT(!scratch3().is(reg)); 1025 ASSERT(!scratch3().is(reg));
1026 ASSERT(!scratch4().is(reg)); 1026 ASSERT(!scratch4().is(reg));
1027 __ push(receiver()); 1027 __ push(receiver());
1028 if (heap()->InNewSpace(callback->data())) { 1028 if (heap()->InNewSpace(callback->data())) {
1029 __ li(scratch3(), callback); 1029 __ li(scratch3(), callback);
1030 __ lw(scratch3(), FieldMemOperand(scratch3(), 1030 __ ld(scratch3(), FieldMemOperand(scratch3(),
1031 ExecutableAccessorInfo::kDataOffset)); 1031 ExecutableAccessorInfo::kDataOffset));
1032 } else { 1032 } else {
1033 __ li(scratch3(), Handle<Object>(callback->data(), isolate())); 1033 __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
1034 } 1034 }
1035 __ Subu(sp, sp, 6 * kPointerSize); 1035 __ Dsubu(sp, sp, 6 * kPointerSize);
1036 __ sw(scratch3(), MemOperand(sp, 5 * kPointerSize)); 1036 __ sd(scratch3(), MemOperand(sp, 5 * kPointerSize));
1037 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 1037 __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
1038 __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize)); 1038 __ sd(scratch3(), MemOperand(sp, 4 * kPointerSize));
1039 __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); 1039 __ sd(scratch3(), MemOperand(sp, 3 * kPointerSize));
1040 __ li(scratch4(), 1040 __ li(scratch4(),
1041 Operand(ExternalReference::isolate_address(isolate()))); 1041 Operand(ExternalReference::isolate_address(isolate())));
1042 __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize)); 1042 __ sd(scratch4(), MemOperand(sp, 2 * kPointerSize));
1043 __ sw(reg, MemOperand(sp, 1 * kPointerSize)); 1043 __ sd(reg, MemOperand(sp, 1 * kPointerSize));
1044 __ sw(name(), MemOperand(sp, 0 * kPointerSize)); 1044 __ sd(name(), MemOperand(sp, 0 * kPointerSize));
1045 __ Addu(scratch2(), sp, 1 * kPointerSize); 1045 __ Daddu(scratch2(), sp, 1 * kPointerSize);
1046 1046
1047 __ mov(a2, scratch2()); // Saved in case scratch2 == a1. 1047 __ mov(a2, scratch2()); // Saved in case scratch2 == a1.
1048 // Abi for CallApiGetter. 1048 // Abi for CallApiGetter.
1049 Register getter_address_reg = a2; 1049 Register getter_address_reg = a2;
1050 1050
1051 Address getter_address = v8::ToCData<Address>(callback->getter()); 1051 Address getter_address = v8::ToCData<Address>(callback->getter());
1052 ApiFunction fun(getter_address); 1052 ApiFunction fun(getter_address);
1053 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 1053 ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
1054 ExternalReference ref = ExternalReference(&fun, type, isolate()); 1054 ExternalReference ref = ExternalReference(&fun, type, isolate());
1055 __ li(getter_address_reg, Operand(ref)); 1055 __ li(getter_address_reg, Operand(ref));
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 { 1187 {
1188 FrameScope scope(masm, StackFrame::INTERNAL); 1188 FrameScope scope(masm, StackFrame::INTERNAL);
1189 1189
1190 // Save value register, so we can restore it later. 1190 // Save value register, so we can restore it later.
1191 __ push(value()); 1191 __ push(value());
1192 1192
1193 if (!setter.is_null()) { 1193 if (!setter.is_null()) {
1194 // Call the JavaScript setter with receiver and value on the stack. 1194 // Call the JavaScript setter with receiver and value on the stack.
1195 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 1195 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1196 // Swap in the global receiver. 1196 // Swap in the global receiver.
1197 __ lw(receiver, 1197 __ ld(receiver,
1198 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 1198 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
1199 } 1199 }
1200 __ Push(receiver, value()); 1200 __ Push(receiver, value());
1201 ParameterCount actual(1); 1201 ParameterCount actual(1);
1202 ParameterCount expected(setter); 1202 ParameterCount expected(setter);
1203 __ InvokeFunction(setter, expected, actual, 1203 __ InvokeFunction(setter, expected, actual,
1204 CALL_FUNCTION, NullCallWrapper()); 1204 CALL_FUNCTION, NullCallWrapper());
1205 } else { 1205 } else {
1206 // If we generate a global code snippet for deoptimization only, remember 1206 // If we generate a global code snippet for deoptimization only, remember
1207 // the place to continue after deoptimization. 1207 // the place to continue after deoptimization.
1208 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 1208 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
1209 } 1209 }
1210 1210
1211 // We have to return the passed value, not the return value of the setter. 1211 // We have to return the passed value, not the return value of the setter.
1212 __ pop(v0); 1212 __ pop(v0);
1213 1213
1214 // Restore context register. 1214 // Restore context register.
1215 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1215 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1216 } 1216 }
1217 __ Ret(); 1217 __ Ret();
1218 } 1218 }
1219 1219
1220 1220
1221 #undef __ 1221 #undef __
1222 #define __ ACCESS_MASM(masm()) 1222 #define __ ACCESS_MASM(masm())
1223 1223
1224 1224
1225 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 1225 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
(...skipping 22 matching lines...) Expand all
1248 1248
1249 // Return the generated code. 1249 // Return the generated code.
1250 return GetCode(kind(), Code::FAST, name); 1250 return GetCode(kind(), Code::FAST, name);
1251 } 1251 }
1252 1252
1253 1253
1254 Register* LoadStubCompiler::registers() { 1254 Register* LoadStubCompiler::registers() {
1255 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1255 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1256 Register receiver = LoadIC::ReceiverRegister(); 1256 Register receiver = LoadIC::ReceiverRegister();
1257 Register name = LoadIC::NameRegister(); 1257 Register name = LoadIC::NameRegister();
1258 static Register registers[] = { receiver, name, a3, a0, t0, t1 }; 1258 static Register registers[] = { receiver, name, a3, a0, a4, a5 };
1259 return registers; 1259 return registers;
1260 } 1260 }
1261 1261
1262 1262
1263 Register* KeyedLoadStubCompiler::registers() { 1263 Register* KeyedLoadStubCompiler::registers() {
1264 // receiver, name, scratch1, scratch2, scratch3, scratch4. 1264 // receiver, name, scratch1, scratch2, scratch3, scratch4.
1265 Register receiver = LoadIC::ReceiverRegister(); 1265 Register receiver = LoadIC::ReceiverRegister();
1266 Register name = LoadIC::NameRegister(); 1266 Register name = LoadIC::NameRegister();
1267 static Register registers[] = { receiver, name, a3, a0, t0, t1 }; 1267 static Register registers[] = { receiver, name, a3, a0, a4, a5 };
1268 return registers; 1268 return registers;
1269 } 1269 }
1270 1270
1271 1271
1272 Register StoreStubCompiler::value() { 1272 Register StoreStubCompiler::value() {
1273 return a0; 1273 return a0;
1274 } 1274 }
1275 1275
1276 1276
1277 Register* StoreStubCompiler::registers() { 1277 Register* StoreStubCompiler::registers() {
1278 // receiver, name, scratch1, scratch2, scratch3. 1278 // receiver, name, scratch1, scratch2, scratch3.
1279 static Register registers[] = { a1, a2, a3, t0, t1 }; 1279 static Register registers[] = { a1, a2, a3, a4, a5 };
1280 return registers; 1280 return registers;
1281 } 1281 }
1282 1282
1283 1283
1284 Register* KeyedStoreStubCompiler::registers() { 1284 Register* KeyedStoreStubCompiler::registers() {
1285 // receiver, name, scratch1, scratch2, scratch3. 1285 // receiver, name, scratch1, scratch2, scratch3.
1286 static Register registers[] = { a2, a1, a3, t0, t1 }; 1286 static Register registers[] = { a2, a1, a3, a4, a5 };
1287 return registers; 1287 return registers;
1288 } 1288 }
1289 1289
1290 1290
1291 #undef __ 1291 #undef __
1292 #define __ ACCESS_MASM(masm) 1292 #define __ ACCESS_MASM(masm)
1293 1293
1294 1294
1295 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 1295 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
1296 Handle<HeapType> type, 1296 Handle<HeapType> type,
1297 Register receiver, 1297 Register receiver,
1298 Handle<JSFunction> getter) { 1298 Handle<JSFunction> getter) {
1299 // ----------- S t a t e ------------- 1299 // ----------- S t a t e -------------
1300 // -- a0 : receiver 1300 // -- a0 : receiver
1301 // -- a2 : name 1301 // -- a2 : name
1302 // -- ra : return address 1302 // -- ra : return address
1303 // ----------------------------------- 1303 // -----------------------------------
1304 { 1304 {
1305 FrameScope scope(masm, StackFrame::INTERNAL); 1305 FrameScope scope(masm, StackFrame::INTERNAL);
1306 1306
1307 if (!getter.is_null()) { 1307 if (!getter.is_null()) {
1308 // Call the JavaScript getter with the receiver on the stack. 1308 // Call the JavaScript getter with the receiver on the stack.
1309 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 1309 if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
1310 // Swap in the global receiver. 1310 // Swap in the global receiver.
1311 __ lw(receiver, 1311 __ ld(receiver,
1312 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 1312 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
1313 } 1313 }
1314 __ push(receiver); 1314 __ push(receiver);
1315 ParameterCount actual(0); 1315 ParameterCount actual(0);
1316 ParameterCount expected(getter); 1316 ParameterCount expected(getter);
1317 __ InvokeFunction(getter, expected, actual, 1317 __ InvokeFunction(getter, expected, actual,
1318 CALL_FUNCTION, NullCallWrapper()); 1318 CALL_FUNCTION, NullCallWrapper());
1319 } else { 1319 } else {
1320 // If we generate a global code snippet for deoptimization only, remember 1320 // If we generate a global code snippet for deoptimization only, remember
1321 // the place to continue after deoptimization. 1321 // the place to continue after deoptimization.
1322 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 1322 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
1323 } 1323 }
1324 1324
1325 // Restore context register. 1325 // Restore context register.
1326 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1326 __ ld(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1327 } 1327 }
1328 __ Ret(); 1328 __ Ret();
1329 } 1329 }
1330 1330
1331 1331
1332 #undef __ 1332 #undef __
1333 #define __ ACCESS_MASM(masm()) 1333 #define __ ACCESS_MASM(masm())
1334 1334
1335 1335
1336 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 1336 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
1337 Handle<HeapType> type, 1337 Handle<HeapType> type,
1338 Handle<GlobalObject> global, 1338 Handle<GlobalObject> global,
1339 Handle<PropertyCell> cell, 1339 Handle<PropertyCell> cell,
1340 Handle<Name> name, 1340 Handle<Name> name,
1341 bool is_dont_delete) { 1341 bool is_dont_delete) {
1342 Label miss; 1342 Label miss;
1343 1343
1344 HandlerFrontendHeader(type, receiver(), global, name, &miss); 1344 HandlerFrontendHeader(type, receiver(), global, name, &miss);
1345 1345
1346 // Get the value from the cell. 1346 // Get the value from the cell.
1347 __ li(a3, Operand(cell)); 1347 __ li(a3, Operand(cell));
1348 __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 1348 __ ld(a4, FieldMemOperand(a3, Cell::kValueOffset));
1349 1349
1350 // Check for deleted property if property can actually be deleted. 1350 // Check for deleted property if property can actually be deleted.
1351 if (!is_dont_delete) { 1351 if (!is_dont_delete) {
1352 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1352 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1353 __ Branch(&miss, eq, t0, Operand(at)); 1353 __ Branch(&miss, eq, a4, Operand(at));
1354 } 1354 }
1355 1355
1356 Counters* counters = isolate()->counters(); 1356 Counters* counters = isolate()->counters();
1357 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 1357 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
1358 __ Ret(USE_DELAY_SLOT); 1358 __ Ret(USE_DELAY_SLOT);
1359 __ mov(v0, t0); 1359 __ mov(v0, a4);
1360 1360
1361 HandlerFrontendFooter(name, &miss); 1361 HandlerFrontendFooter(name, &miss);
1362 1362
1363 // Return the generated code. 1363 // Return the generated code.
1364 return GetCode(kind(), Code::NORMAL, name); 1364 return GetCode(kind(), Code::NORMAL, name);
1365 } 1365 }
1366 1366
1367 1367
1368 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 1368 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
1369 TypeHandleList* types, 1369 TypeHandleList* types,
(...skipping 10 matching lines...) Expand all
1380 1380
1381 Label number_case; 1381 Label number_case;
1382 Register match = scratch1(); 1382 Register match = scratch1();
1383 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 1383 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
1384 __ JumpIfSmi(receiver(), smi_target, match); // Reg match is 0 if Smi. 1384 __ JumpIfSmi(receiver(), smi_target, match); // Reg match is 0 if Smi.
1385 1385
1386 Register map_reg = scratch2(); 1386 Register map_reg = scratch2();
1387 1387
1388 int receiver_count = types->length(); 1388 int receiver_count = types->length();
1389 int number_of_handled_maps = 0; 1389 int number_of_handled_maps = 0;
1390 __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 1390 __ ld(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
1391 for (int current = 0; current < receiver_count; ++current) { 1391 for (int current = 0; current < receiver_count; ++current) {
1392 Handle<HeapType> type = types->at(current); 1392 Handle<HeapType> type = types->at(current);
1393 Handle<Map> map = IC::TypeToMap(*type, isolate()); 1393 Handle<Map> map = IC::TypeToMap(*type, isolate());
1394 if (!map->is_deprecated()) { 1394 if (!map->is_deprecated()) {
1395 number_of_handled_maps++; 1395 number_of_handled_maps++;
1396 // Check map and tail call if there's a match. 1396 // Check map and tail call if there's a match.
1397 // Separate compare from branch, to provide path for above JumpIfSmi(). 1397 // Separate compare from branch, to provide path for above JumpIfSmi().
1398 __ Subu(match, map_reg, Operand(map)); 1398 __ Dsubu(match, map_reg, Operand(map));
1399 if (type->Is(HeapType::Number())) { 1399 if (type->Is(HeapType::Number())) {
1400 ASSERT(!number_case.is_unused()); 1400 ASSERT(!number_case.is_unused());
1401 __ bind(&number_case); 1401 __ bind(&number_case);
1402 } 1402 }
1403 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, 1403 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET,
1404 eq, match, Operand(zero_reg)); 1404 eq, match, Operand(zero_reg));
1405 } 1405 }
1406 } 1406 }
1407 ASSERT(number_of_handled_maps != 0); 1407 ASSERT(number_of_handled_maps != 0);
1408 1408
(...skipping 19 matching lines...) Expand all
1428 1428
1429 1429
1430 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 1430 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
1431 MapHandleList* receiver_maps, 1431 MapHandleList* receiver_maps,
1432 CodeHandleList* handler_stubs, 1432 CodeHandleList* handler_stubs,
1433 MapHandleList* transitioned_maps) { 1433 MapHandleList* transitioned_maps) {
1434 Label miss; 1434 Label miss;
1435 __ JumpIfSmi(receiver(), &miss); 1435 __ JumpIfSmi(receiver(), &miss);
1436 1436
1437 int receiver_count = receiver_maps->length(); 1437 int receiver_count = receiver_maps->length();
1438 __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); 1438 __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
1439 for (int i = 0; i < receiver_count; ++i) { 1439 for (int i = 0; i < receiver_count; ++i) {
1440 if (transitioned_maps->at(i).is_null()) { 1440 if (transitioned_maps->at(i).is_null()) {
1441 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, 1441 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq,
1442 scratch1(), Operand(receiver_maps->at(i))); 1442 scratch1(), Operand(receiver_maps->at(i)));
1443 } else { 1443 } else {
1444 Label next_map; 1444 Label next_map;
1445 __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); 1445 __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
1446 __ li(transition_map(), Operand(transitioned_maps->at(i))); 1446 __ li(transition_map(), Operand(transitioned_maps->at(i)));
1447 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); 1447 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
1448 __ bind(&next_map); 1448 __ bind(&next_map);
1449 } 1449 }
1450 } 1450 }
1451 1451
1452 __ bind(&miss); 1452 __ bind(&miss);
1453 TailCallBuiltin(masm(), MissBuiltin(kind())); 1453 TailCallBuiltin(masm(), MissBuiltin(kind()));
1454 1454
1455 // Return the generated code. 1455 // Return the generated code.
1456 return GetICCode( 1456 return GetICCode(
1457 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 1457 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
1458 } 1458 }
1459 1459
1460 1460
1461 #undef __ 1461 #undef __
1462 #define __ ACCESS_MASM(masm) 1462 #define __ ACCESS_MASM(masm)
1463 1463
1464 1464
1465 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 1465 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
1466 MacroAssembler* masm) { 1466 MacroAssembler* masm) {
1467 // The return address is in ra. 1467 // The return address is in ra
1468 Label slow, miss; 1468 Label slow, miss;
1469 1469
1470 Register key = LoadIC::NameRegister(); 1470 Register key = LoadIC::NameRegister();
1471 Register receiver = LoadIC::ReceiverRegister(); 1471 Register receiver = LoadIC::ReceiverRegister();
1472 ASSERT(receiver.is(a1)); 1472 ASSERT(receiver.is(a1));
1473 ASSERT(key.is(a2)); 1473 ASSERT(key.is(a2));
1474 1474
1475 __ UntagAndJumpIfNotSmi(t2, key, &miss); 1475 __ UntagAndJumpIfNotSmi(a6, key, &miss);
1476 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1476 __ ld(a4, FieldMemOperand(receiver, JSObject::kElementsOffset));
1477 __ LoadFromNumberDictionary(&slow, t0, key, v0, t2, a3, t1); 1477 ASSERT(kSmiTagSize + kSmiShiftSize == 32);
1478 __ LoadFromNumberDictionary(&slow, a4, key, v0, a6, a3, a5);
1478 __ Ret(); 1479 __ Ret();
1479 1480
1480 // Slow case, key and receiver still unmodified. 1481 // Slow case, key and receiver still unmodified.
1481 __ bind(&slow); 1482 __ bind(&slow);
1482 __ IncrementCounter( 1483 __ IncrementCounter(
1483 masm->isolate()->counters()->keyed_load_external_array_slow(), 1484 masm->isolate()->counters()->keyed_load_external_array_slow(),
1484 1, a2, a3); 1485 1, a2, a3);
1485 1486
1486 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); 1487 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
1487 1488
1488 // Miss case, call the runtime. 1489 // Miss case, call the runtime.
1489 __ bind(&miss); 1490 __ bind(&miss);
1490 1491
1491 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1492 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1492 } 1493 }
1493 1494
1494 1495
1495 #undef __ 1496 #undef __
1496 1497
1497 } } // namespace v8::internal 1498 } } // namespace v8::internal
1498 1499
1499 #endif // V8_TARGET_ARCH_MIPS 1500 #endif // V8_TARGET_ARCH_MIPS64
OLDNEW
« no previous file with comments | « src/mips64/simulator-mips64.cc ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698