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

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

Issue 2330003: Change the interface of LoadIC on the x64 platform to take its arguments in r... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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/x64/full-codegen-x64.cc ('k') | src/x64/stub-cache-x64.cc » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // This function may return false negatives, so miss_label 49 // This function may return false negatives, so miss_label
50 // must always call a backup property load that is complete. 50 // must always call a backup property load that is complete.
51 // This function is safe to call if the receiver has fast properties, 51 // This function is safe to call if the receiver has fast properties,
52 // or if name is not a symbol, and will jump to the miss_label in that case. 52 // or if name is not a symbol, and will jump to the miss_label in that case.
53 static void GenerateDictionaryLoad(MacroAssembler* masm, 53 static void GenerateDictionaryLoad(MacroAssembler* masm,
54 Label* miss_label, 54 Label* miss_label,
55 Register r0, 55 Register r0,
56 Register r1, 56 Register r1,
57 Register r2, 57 Register r2,
58 Register name, 58 Register name,
59 Register r4,
59 DictionaryCheck check_dictionary) { 60 DictionaryCheck check_dictionary) {
60 // Register use: 61 // Register use:
61 // 62 //
62 // r0 - used to hold the property dictionary. 63 // r0 - used to hold the property dictionary.
63 // 64 //
64 // r1 - initially the receiver 65 // r1 - initially the receiver.
65 // - used for the index into the property dictionary 66 // - unchanged on any jump to miss_label.
66 // - holds the result on exit. 67 // - holds the result on exit.
67 // 68 //
68 // r2 - used to hold the capacity of the property dictionary. 69 // r2 - used to hold the capacity of the property dictionary.
69 // 70 //
70 // name - holds the name of the property and is unchanged. 71 // name - holds the name of the property and is unchanged.
72 // r4 - used to hold the index into the property dictionary.
71 73
72 Label done; 74 Label done;
73 75
74 // Check for the absence of an interceptor. 76 // Check for the absence of an interceptor.
75 // Load the map into r0. 77 // Load the map into r0.
76 __ movq(r0, FieldOperand(r1, JSObject::kMapOffset)); 78 __ movq(r0, FieldOperand(r1, JSObject::kMapOffset));
77 79
78 // Bail out if the receiver has a named interceptor. 80 // Bail out if the receiver has a named interceptor.
79 __ testl(FieldOperand(r0, Map::kBitFieldOffset), 81 __ testl(FieldOperand(r0, Map::kBitFieldOffset),
80 Immediate(1 << Map::kHasNamedInterceptor)); 82 Immediate(1 << Map::kHasNamedInterceptor));
(...skipping 28 matching lines...) Expand all
109 111
110 // Generate an unrolled loop that performs a few probes before 112 // Generate an unrolled loop that performs a few probes before
111 // giving up. Measurements done on Gmail indicate that 2 probes 113 // giving up. Measurements done on Gmail indicate that 2 probes
112 // cover ~93% of loads from dictionaries. 114 // cover ~93% of loads from dictionaries.
113 static const int kProbes = 4; 115 static const int kProbes = 4;
114 const int kElementsStartOffset = 116 const int kElementsStartOffset =
115 StringDictionary::kHeaderSize + 117 StringDictionary::kHeaderSize +
116 StringDictionary::kElementsStartIndex * kPointerSize; 118 StringDictionary::kElementsStartIndex * kPointerSize;
117 for (int i = 0; i < kProbes; i++) { 119 for (int i = 0; i < kProbes; i++) {
118 // Compute the masked index: (hash + i + i * i) & mask. 120 // Compute the masked index: (hash + i + i * i) & mask.
119 __ movl(r1, FieldOperand(name, String::kHashFieldOffset)); 121 __ movl(r4, FieldOperand(name, String::kHashFieldOffset));
120 __ shrl(r1, Immediate(String::kHashShift)); 122 __ shrl(r4, Immediate(String::kHashShift));
121 if (i > 0) { 123 if (i > 0) {
122 __ addl(r1, Immediate(StringDictionary::GetProbeOffset(i))); 124 __ addl(r4, Immediate(StringDictionary::GetProbeOffset(i)));
123 } 125 }
124 __ and_(r1, r2); 126 __ and_(r4, r2);
125 127
126 // Scale the index by multiplying by the entry size. 128 // Scale the index by multiplying by the entry size.
127 ASSERT(StringDictionary::kEntrySize == 3); 129 ASSERT(StringDictionary::kEntrySize == 3);
128 __ lea(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 130 __ lea(r4, Operand(r4, r4, times_2, 0)); // r4 = r4 * 3
129 131
130 // Check if the key is identical to the name. 132 // Check if the key is identical to the name.
131 __ cmpq(name, Operand(r0, r1, times_pointer_size, 133 __ cmpq(name, Operand(r0, r4, times_pointer_size,
132 kElementsStartOffset - kHeapObjectTag)); 134 kElementsStartOffset - kHeapObjectTag));
133 if (i != kProbes - 1) { 135 if (i != kProbes - 1) {
134 __ j(equal, &done); 136 __ j(equal, &done);
135 } else { 137 } else {
136 __ j(not_equal, miss_label); 138 __ j(not_equal, miss_label);
137 } 139 }
138 } 140 }
139 141
140 // Check that the value is a normal property. 142 // Check that the value is a normal property.
141 __ bind(&done); 143 __ bind(&done);
142 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 144 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
143 __ Test(Operand(r0, r1, times_pointer_size, kDetailsOffset - kHeapObjectTag), 145 __ Test(Operand(r0, r4, times_pointer_size, kDetailsOffset - kHeapObjectTag),
144 Smi::FromInt(PropertyDetails::TypeField::mask())); 146 Smi::FromInt(PropertyDetails::TypeField::mask()));
145 __ j(not_zero, miss_label); 147 __ j(not_zero, miss_label);
146 148
147 // Get the value at the masked, scaled index. 149 // Get the value at the masked, scaled index.
148 const int kValueOffset = kElementsStartOffset + kPointerSize; 150 const int kValueOffset = kElementsStartOffset + kPointerSize;
149 __ movq(r1, 151 __ movq(r1,
150 Operand(r0, r1, times_pointer_size, kValueOffset - kHeapObjectTag)); 152 Operand(r0, r4, times_pointer_size, kValueOffset - kHeapObjectTag));
151 } 153 }
152 154
153 155
154 static void GenerateNumberDictionaryLoad(MacroAssembler* masm, 156 static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
155 Label* miss, 157 Label* miss,
156 Register elements, 158 Register elements,
157 Register key, 159 Register key,
158 Register r0, 160 Register r0,
159 Register r1, 161 Register r1,
160 Register r2) { 162 Register r2) {
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 496
495 // Do a quick inline probe of the receiver's dictionary, if it 497 // Do a quick inline probe of the receiver's dictionary, if it
496 // exists. 498 // exists.
497 __ bind(&probe_dictionary); 499 __ bind(&probe_dictionary);
498 GenerateDictionaryLoad(masm, 500 GenerateDictionaryLoad(masm,
499 &slow, 501 &slow,
500 rbx, 502 rbx,
501 rcx, 503 rcx,
502 rdx, 504 rdx,
503 rax, 505 rax,
506 rdi,
504 DICTIONARY_CHECK_DONE); 507 DICTIONARY_CHECK_DONE);
505 __ movq(rax, rcx); 508 __ movq(rax, rcx);
506 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 509 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
507 __ ret(0); 510 __ ret(0);
508 // If the hash field contains an array index pick it out. The assert checks 511 // If the hash field contains an array index pick it out. The assert checks
509 // that the constants for the maximum number of digits for an array index 512 // that the constants for the maximum number of digits for an array index
510 // cached in the hash field and the number of bits reserved for it does not 513 // cached in the hash field and the number of bits reserved for it does not
511 // conflict. 514 // conflict.
512 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 515 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
513 (1 << String::kArrayIndexValueBits)); 516 (1 << String::kArrayIndexValueBits));
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 // rcx : function name 1224 // rcx : function name
1222 // rdx : receiver 1225 // rdx : receiver
1223 // rsp[0] : return address 1226 // rsp[0] : return address
1224 // rsp[8] : argument argc 1227 // rsp[8] : argument argc
1225 // rsp[16] : argument argc - 1 1228 // rsp[16] : argument argc - 1
1226 // ... 1229 // ...
1227 // rsp[argc * 8] : argument 1 1230 // rsp[argc * 8] : argument 1
1228 // rsp[(argc + 1) * 8] : argument 0 = receiver 1231 // rsp[(argc + 1) * 8] : argument 0 = receiver
1229 // ----------------------------------- 1232 // -----------------------------------
1230 // Search dictionary - put result in register rdx. 1233 // Search dictionary - put result in register rdx.
1231 GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx, CHECK_DICTIONARY); 1234 GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx, rdi, CHECK_DICTIONARY);
1232 1235
1233 // Move the result to register rdi and check that it isn't a smi. 1236 // Move the result to register rdi and check that it isn't a smi.
1234 __ movq(rdi, rdx); 1237 __ movq(rdi, rdx);
1235 __ JumpIfSmi(rdx, miss); 1238 __ JumpIfSmi(rdx, miss);
1236 1239
1237 // Check that the value is a JavaScript function. 1240 // Check that the value is a JavaScript function.
1238 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rdx); 1241 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rdx);
1239 __ j(not_equal, miss); 1242 __ j(not_equal, miss);
1240 1243
1241 // Patch the receiver with the global proxy if necessary. 1244 // Patch the receiver with the global proxy if necessary.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1326 void LoadIC::ClearInlinedVersion(Address address) { 1329 void LoadIC::ClearInlinedVersion(Address address) {
1327 // Reset the map check of the inlined inobject property load (if 1330 // Reset the map check of the inlined inobject property load (if
1328 // present) to guarantee failure by holding an invalid map (the null 1331 // present) to guarantee failure by holding an invalid map (the null
1329 // value). The offset can be patched to anything. 1332 // value). The offset can be patched to anything.
1330 PatchInlinedLoad(address, Heap::null_value(), kMaxInt); 1333 PatchInlinedLoad(address, Heap::null_value(), kMaxInt);
1331 } 1334 }
1332 1335
1333 1336
1334 void LoadIC::GenerateMiss(MacroAssembler* masm) { 1337 void LoadIC::GenerateMiss(MacroAssembler* masm) {
1335 // ----------- S t a t e ------------- 1338 // ----------- S t a t e -------------
1339 // -- rax : receiver
1336 // -- rcx : name 1340 // -- rcx : name
1337 // -- rsp[0] : return address 1341 // -- rsp[0] : return address
1338 // -- rsp[8] : receiver
1339 // ----------------------------------- 1342 // -----------------------------------
1340 1343
1341 __ pop(rbx); 1344 __ pop(rbx);
1342 __ push(Operand(rsp, 0)); // receiver 1345 __ push(rax); // receiver
1343 __ push(rcx); // name 1346 __ push(rcx); // name
1344 __ push(rbx); // return address 1347 __ push(rbx); // return address
1345 1348
1346 // Perform tail call to the entry. 1349 // Perform tail call to the entry.
1347 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); 1350 ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss));
1348 __ TailCallExternalReference(ref, 2, 1); 1351 __ TailCallExternalReference(ref, 2, 1);
1349 } 1352 }
1350 1353
1351 1354
1352 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 1355 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
1353 // ----------- S t a t e ------------- 1356 // ----------- S t a t e -------------
1357 // -- rax : receiver
1354 // -- rcx : name 1358 // -- rcx : name
1355 // -- rsp[0] : return address 1359 // -- rsp[0] : return address
1356 // -- rsp[8] : receiver
1357 // ----------------------------------- 1360 // -----------------------------------
1358 Label miss; 1361 Label miss;
1359 1362
1360 __ movq(rax, Operand(rsp, kPointerSize));
1361
1362 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss); 1363 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
1363 __ bind(&miss); 1364 __ bind(&miss);
1364 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1365 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1365 } 1366 }
1366 1367
1367 1368
1368 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) { 1369 void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
1369 // ----------- S t a t e ------------- 1370 // ----------- S t a t e -------------
1371 // -- rax : receiver
1370 // -- rcx : name 1372 // -- rcx : name
1371 // -- rsp[0] : return address 1373 // -- rsp[0] : return address
1372 // -- rsp[8] : receiver
1373 // ----------------------------------- 1374 // -----------------------------------
1374 Label miss; 1375 Label miss;
1375 1376
1376 __ movq(rax, Operand(rsp, kPointerSize));
1377
1378 StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss); 1377 StubCompiler::GenerateLoadFunctionPrototype(masm, rax, rdx, rbx, &miss);
1379 __ bind(&miss); 1378 __ bind(&miss);
1380 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1379 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1381 } 1380 }
1382 1381
1383 1382
1384 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 1383 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1385 // ----------- S t a t e ------------- 1384 // ----------- S t a t e -------------
1385 // -- rax : receiver
1386 // -- rcx : name 1386 // -- rcx : name
1387 // -- rsp[0] : return address 1387 // -- rsp[0] : return address
1388 // -- rsp[8] : receiver
1389 // ----------------------------------- 1388 // -----------------------------------
1390 1389
1391 __ movq(rax, Operand(rsp, kPointerSize));
1392
1393 // Probe the stub cache. 1390 // Probe the stub cache.
1394 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, 1391 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
1395 NOT_IN_LOOP, 1392 NOT_IN_LOOP,
1396 MONOMORPHIC); 1393 MONOMORPHIC);
1397 StubCache::GenerateProbe(masm, flags, rax, rcx, rbx, rdx); 1394 StubCache::GenerateProbe(masm, flags, rax, rcx, rbx, rdx);
1398 1395
1399 // Cache miss: Jump to runtime. 1396 // Cache miss: Jump to runtime.
1400 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1397 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1401 } 1398 }
1402 1399
1403 1400
1404 void LoadIC::GenerateNormal(MacroAssembler* masm) { 1401 void LoadIC::GenerateNormal(MacroAssembler* masm) {
1405 // ----------- S t a t e ------------- 1402 // ----------- S t a t e -------------
1403 // -- rax : receiver
1406 // -- rcx : name 1404 // -- rcx : name
1407 // -- rsp[0] : return address 1405 // -- rsp[0] : return address
1408 // -- rsp[8] : receiver
1409 // ----------------------------------- 1406 // -----------------------------------
1410 Label miss, probe, global; 1407 Label miss, probe, global;
1411 1408
1412 __ movq(rax, Operand(rsp, kPointerSize));
1413
1414 // Check that the receiver isn't a smi. 1409 // Check that the receiver isn't a smi.
1415 __ JumpIfSmi(rax, &miss); 1410 __ JumpIfSmi(rax, &miss);
1416 1411
1417 // Check that the receiver is a valid JS object. 1412 // Check that the receiver is a valid JS object.
1418 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx); 1413 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
1419 __ j(below, &miss); 1414 __ j(below, &miss);
1420 1415
1421 // If this assert fails, we have to check upper bound too. 1416 // If this assert fails, we have to check upper bound too.
1422 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 1417 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
1423 1418
1424 // Check for access to global object (unlikely). 1419 // Check for access to global object (unlikely).
1425 __ CmpInstanceType(rbx, JS_GLOBAL_PROXY_TYPE); 1420 __ CmpInstanceType(rbx, JS_GLOBAL_PROXY_TYPE);
1426 __ j(equal, &global); 1421 __ j(equal, &global);
1427 1422
1428 // Check for non-global object that requires access check. 1423 // Check for non-global object that requires access check.
1429 __ testl(FieldOperand(rbx, Map::kBitFieldOffset), 1424 __ testl(FieldOperand(rbx, Map::kBitFieldOffset),
1430 Immediate(1 << Map::kIsAccessCheckNeeded)); 1425 Immediate(1 << Map::kIsAccessCheckNeeded));
1431 __ j(not_zero, &miss); 1426 __ j(not_zero, &miss);
1432 1427
1433 // Search the dictionary placing the result in rax. 1428 // Search the dictionary placing the result in rax.
1434 __ bind(&probe); 1429 __ bind(&probe);
1435 GenerateDictionaryLoad(masm, &miss, rdx, rax, rbx, rcx, CHECK_DICTIONARY); 1430 GenerateDictionaryLoad(masm, &miss, rdx, rax, rbx,
1431 rcx, rdi, CHECK_DICTIONARY);
1436 __ ret(0); 1432 __ ret(0);
1437 1433
1438 // Global object access: Check access rights. 1434 // Global object access: Check access rights.
1439 __ bind(&global); 1435 __ bind(&global);
1440 __ CheckAccessGlobalProxy(rax, rdx, &miss); 1436 __ CheckAccessGlobalProxy(rax, rdx, &miss);
1441 __ jmp(&probe); 1437 __ jmp(&probe);
1442 1438
1443 // Cache miss: Restore receiver from stack and jump to runtime. 1439 // Cache miss: Jump to runtime.
1444 __ bind(&miss); 1440 __ bind(&miss);
1445 __ movq(rax, Operand(rsp, 1 * kPointerSize));
1446 GenerateMiss(masm); 1441 GenerateMiss(masm);
1447 } 1442 }
1448 1443
1449 1444
1450 void LoadIC::GenerateStringLength(MacroAssembler* masm) { 1445 void LoadIC::GenerateStringLength(MacroAssembler* masm) {
1451 // ----------- S t a t e ------------- 1446 // ----------- S t a t e -------------
1447 // -- rax : receiver
1452 // -- rcx : name 1448 // -- rcx : name
1453 // -- rsp[0] : return address 1449 // -- rsp[0] : return address
1454 // -- rsp[8] : receiver
1455 // ----------------------------------- 1450 // -----------------------------------
1456 Label miss; 1451 Label miss;
1457 1452
1458 __ movq(rax, Operand(rsp, kPointerSize));
1459
1460 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss); 1453 StubCompiler::GenerateLoadStringLength(masm, rax, rdx, rbx, &miss);
1461 __ bind(&miss); 1454 __ bind(&miss);
1462 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); 1455 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
1463 } 1456 }
1464 1457
1465 1458
1466 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) { 1459 bool LoadIC::PatchInlinedLoad(Address address, Object* map, int offset) {
1467 // The address of the instruction following the call. 1460 // The address of the instruction following the call.
1468 Address test_instruction_address = 1461 Address test_instruction_address =
1469 address + Assembler::kCallTargetAddressOffset; 1462 address + Assembler::kCallTargetAddressOffset;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 GenerateMiss(masm); 1572 GenerateMiss(masm);
1580 } 1573 }
1581 1574
1582 1575
1583 #undef __ 1576 #undef __
1584 1577
1585 1578
1586 } } // namespace v8::internal 1579 } } // namespace v8::internal
1587 1580
1588 #endif // V8_TARGET_ARCH_X64 1581 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698