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

Side by Side Diff: src/mips/ic-mips.cc

Issue 7227010: Create and use shared stub for for DictionaryValue-based elements. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: more arm fixes Created 9 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/ic.cc ('k') | src/mips/macro-assembler-mips.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 const int kValueOffset = kElementsStartOffset + kPointerSize; 207 const int kValueOffset = kElementsStartOffset + kPointerSize;
208 __ Addu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag)); 208 __ Addu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag));
209 __ sw(value, MemOperand(scratch2)); 209 __ sw(value, MemOperand(scratch2));
210 210
211 // Update the write barrier. Make sure not to clobber the value. 211 // Update the write barrier. Make sure not to clobber the value.
212 __ mov(scratch1, value); 212 __ mov(scratch1, value);
213 __ RecordWrite(elements, scratch2, scratch1); 213 __ RecordWrite(elements, scratch2, scratch1);
214 } 214 }
215 215
216 216
217 static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
218 Label* miss,
219 Register elements,
220 Register key,
221 Register result,
222 Register reg0,
223 Register reg1,
224 Register reg2) {
225 // Register use:
226 //
227 // elements - holds the slow-case elements of the receiver on entry.
228 // Unchanged unless 'result' is the same register.
229 //
230 // key - holds the smi key on entry.
231 // Unchanged unless 'result' is the same register.
232 //
233 //
234 // result - holds the result on exit if the load succeeded.
235 // Allowed to be the same as 'key' or 'result'.
236 // Unchanged on bailout so 'key' or 'result' can be used
237 // in further computation.
238 //
239 // Scratch registers:
240 //
241 // reg0 - holds the untagged key on entry and holds the hash once computed.
242 //
243 // reg1 - Used to hold the capacity mask of the dictionary.
244 //
245 // reg2 - Used for the index into the dictionary.
246 // at - Temporary (avoid MacroAssembler instructions also using 'at').
247 Label done;
248
249 // Compute the hash code from the untagged key. This must be kept in sync
250 // with ComputeIntegerHash in utils.h.
251 //
252 // hash = ~hash + (hash << 15);
253 __ nor(reg1, reg0, zero_reg);
254 __ sll(at, reg0, 15);
255 __ addu(reg0, reg1, at);
256
257 // hash = hash ^ (hash >> 12);
258 __ srl(at, reg0, 12);
259 __ xor_(reg0, reg0, at);
260
261 // hash = hash + (hash << 2);
262 __ sll(at, reg0, 2);
263 __ addu(reg0, reg0, at);
264
265 // hash = hash ^ (hash >> 4);
266 __ srl(at, reg0, 4);
267 __ xor_(reg0, reg0, at);
268
269 // hash = hash * 2057;
270 __ li(reg1, Operand(2057));
271 __ mul(reg0, reg0, reg1);
272
273 // hash = hash ^ (hash >> 16);
274 __ srl(at, reg0, 16);
275 __ xor_(reg0, reg0, at);
276
277 // Compute the capacity mask.
278 __ lw(reg1, FieldMemOperand(elements, NumberDictionary::kCapacityOffset));
279 __ sra(reg1, reg1, kSmiTagSize);
280 __ Subu(reg1, reg1, Operand(1));
281
282 // Generate an unrolled loop that performs a few probes before giving up.
283 static const int kProbes = 4;
284 for (int i = 0; i < kProbes; i++) {
285 // Use reg2 for index calculations and keep the hash intact in reg0.
286 __ mov(reg2, reg0);
287 // Compute the masked index: (hash + i + i * i) & mask.
288 if (i > 0) {
289 __ Addu(reg2, reg2, Operand(NumberDictionary::GetProbeOffset(i)));
290 }
291 __ and_(reg2, reg2, reg1);
292
293 // Scale the index by multiplying by the element size.
294 ASSERT(NumberDictionary::kEntrySize == 3);
295 __ sll(at, reg2, 1); // 2x.
296 __ addu(reg2, reg2, at); // reg2 = reg2 * 3.
297
298 // Check if the key is identical to the name.
299 __ sll(at, reg2, kPointerSizeLog2);
300 __ addu(reg2, elements, at);
301
302 __ lw(at, FieldMemOperand(reg2, NumberDictionary::kElementsStartOffset));
303 if (i != kProbes - 1) {
304 __ Branch(&done, eq, key, Operand(at));
305 } else {
306 __ Branch(miss, ne, key, Operand(at));
307 }
308 }
309
310 __ bind(&done);
311 // Check that the value is a normal property.
312 // reg2: elements + (index * kPointerSize).
313 const int kDetailsOffset =
314 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
315 __ lw(reg1, FieldMemOperand(reg2, kDetailsOffset));
316 __ And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask())));
317 __ Branch(miss, ne, at, Operand(zero_reg));
318
319 // Get the value at the masked, scaled index and return.
320 const int kValueOffset =
321 NumberDictionary::kElementsStartOffset + kPointerSize;
322 __ lw(result, FieldMemOperand(reg2, kValueOffset));
323 }
324
325
326 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 217 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
327 // ----------- S t a t e ------------- 218 // ----------- S t a t e -------------
328 // -- a2 : name 219 // -- a2 : name
329 // -- ra : return address 220 // -- ra : return address
330 // -- a0 : receiver 221 // -- a0 : receiver
331 // -- sp[0] : receiver 222 // -- sp[0] : receiver
332 // ----------------------------------- 223 // -----------------------------------
333 Label miss; 224 Label miss;
334 225
335 StubCompiler::GenerateLoadArrayLength(masm, a0, a3, &miss); 226 StubCompiler::GenerateLoadArrayLength(masm, a0, a3, &miss);
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 635
745 __ bind(&check_number_dictionary); 636 __ bind(&check_number_dictionary);
746 // a2: key 637 // a2: key
747 // a3: elements map 638 // a3: elements map
748 // t0: elements pointer 639 // t0: elements pointer
749 // Check whether the elements is a number dictionary. 640 // Check whether the elements is a number dictionary.
750 __ LoadRoot(at, Heap::kHashTableMapRootIndex); 641 __ LoadRoot(at, Heap::kHashTableMapRootIndex);
751 __ Branch(&slow_load, ne, a3, Operand(at)); 642 __ Branch(&slow_load, ne, a3, Operand(at));
752 __ sra(a0, a2, kSmiTagSize); 643 __ sra(a0, a2, kSmiTagSize);
753 // a0: untagged index 644 // a0: untagged index
754 GenerateNumberDictionaryLoad(masm, &slow_load, t0, a2, a1, a0, a3, t1); 645 __ LoadFromNumberDictionary(&slow_load, t0, a2, a1, a0, a3, t1);
755 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, a0, a3); 646 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1, a0, a3);
756 __ jmp(&do_call); 647 __ jmp(&do_call);
757 648
758 __ bind(&slow_load); 649 __ bind(&slow_load);
759 // This branch is taken when calling KeyedCallIC_Miss is neither required 650 // This branch is taken when calling KeyedCallIC_Miss is neither required
760 // nor beneficial. 651 // nor beneficial.
761 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, a0, a3); 652 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1, a0, a3);
762 __ EnterInternalFrame(); 653 __ EnterInternalFrame();
763 __ push(a2); // Save the key. 654 __ push(a2); // Save the key.
764 __ Push(a1, a2); // Pass the receiver and the key. 655 __ Push(a1, a2); // Pass the receiver and the key.
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 1020 __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset));
1130 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset)); 1021 __ lw(a3, FieldMemOperand(t0, JSObject::kMapOffset));
1131 1022
1132 // Check whether the elements is a number dictionary. 1023 // Check whether the elements is a number dictionary.
1133 // a0: key 1024 // a0: key
1134 // a3: elements map 1025 // a3: elements map
1135 // t0: elements 1026 // t0: elements
1136 __ LoadRoot(at, Heap::kHashTableMapRootIndex); 1027 __ LoadRoot(at, Heap::kHashTableMapRootIndex);
1137 __ Branch(&slow, ne, a3, Operand(at)); 1028 __ Branch(&slow, ne, a3, Operand(at));
1138 __ sra(a2, a0, kSmiTagSize); 1029 __ sra(a2, a0, kSmiTagSize);
1139 GenerateNumberDictionaryLoad(masm, &slow, t0, a0, v0, a2, a3, t1); 1030 __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1);
1140 __ Ret(); 1031 __ Ret();
1141 1032
1142 // Slow case, key and receiver still in a0 and a1. 1033 // Slow case, key and receiver still in a0 and a1.
1143 __ bind(&slow); 1034 __ bind(&slow);
1144 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1035 __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(),
1145 1, 1036 1,
1146 a2, 1037 a2,
1147 a3); 1038 a3);
1148 GenerateRuntimeGetProperty(masm); 1039 GenerateRuntimeGetProperty(masm);
1149 1040
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch)); 1628 Register reg = Register::from_code(Assembler::GetRs(instr_at_patch));
1738 patcher.masm()->andi(at, reg, kSmiTagMask); 1629 patcher.masm()->andi(at, reg, kSmiTagMask);
1739 patcher.ChangeBranchCondition(eq); 1630 patcher.ChangeBranchCondition(eq);
1740 } 1631 }
1741 } 1632 }
1742 1633
1743 1634
1744 } } // namespace v8::internal 1635 } } // namespace v8::internal
1745 1636
1746 #endif // V8_TARGET_ARCH_MIPS 1637 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/ic.cc ('k') | src/mips/macro-assembler-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698