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

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

Issue 2073018: Reverting r4703. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 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/macro-assembler-x64.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 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 Register key, 158 Register key,
159 Register r0, 159 Register r0,
160 Register r1, 160 Register r1,
161 Register r2) { 161 Register r2) {
162 // Register use: 162 // Register use:
163 // 163 //
164 // elements - holds the slow-case elements of the receiver and is unchanged. 164 // elements - holds the slow-case elements of the receiver and is unchanged.
165 // 165 //
166 // key - holds the smi key on entry and is unchanged if a branch is 166 // key - holds the smi key on entry and is unchanged if a branch is
167 // performed to the miss label. 167 // performed to the miss label.
168 // Holds the result on exit if the load succeeded.
169 // 168 //
170 // Scratch registers: 169 // Scratch registers:
171 // 170 //
172 // r0 - holds the untagged key on entry and holds the hash once computed. 171 // r0 - holds the untagged key on entry and holds the hash once computed.
172 // Holds the result on exit if the load succeeded.
173 // 173 //
174 // r1 - used to hold the capacity mask of the dictionary 174 // r1 - used to hold the capacity mask of the dictionary
175 // 175 //
176 // r2 - used for the index into the dictionary. 176 // r2 - used for the index into the dictionary.
177 Label done; 177 Label done;
178 178
179 // Compute the hash code from the untagged key. This must be kept in sync 179 // Compute the hash code from the untagged key. This must be kept in sync
180 // with ComputeIntegerHash in utils.h. 180 // with ComputeIntegerHash in utils.h.
181 // 181 //
182 // hash = ~hash + (hash << 15); 182 // hash = ~hash + (hash << 15);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 const int kDetailsOffset = 238 const int kDetailsOffset =
239 NumberDictionary::kElementsStartOffset + 2 * kPointerSize; 239 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
240 ASSERT_EQ(NORMAL, 0); 240 ASSERT_EQ(NORMAL, 0);
241 __ Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), 241 __ Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
242 Smi::FromInt(PropertyDetails::TypeField::mask())); 242 Smi::FromInt(PropertyDetails::TypeField::mask()));
243 __ j(not_zero, miss); 243 __ j(not_zero, miss);
244 244
245 // Get the value at the masked, scaled index. 245 // Get the value at the masked, scaled index.
246 const int kValueOffset = 246 const int kValueOffset =
247 NumberDictionary::kElementsStartOffset + kPointerSize; 247 NumberDictionary::kElementsStartOffset + kPointerSize;
248 __ movq(key, FieldOperand(elements, r2, times_pointer_size, kValueOffset)); 248 __ movq(r0, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
249 } 249 }
250 250
251 251
252 // One byte opcode for test eax,0xXXXXXXXX. 252 // One byte opcode for test eax,0xXXXXXXXX.
253 static const byte kTestEaxByte = 0xA9; 253 static const byte kTestEaxByte = 0xA9;
254 254
255 255
256 static bool PatchInlinedMapCheck(Address address, Object* map) { 256 static bool PatchInlinedMapCheck(Address address, Object* map) {
257 // Arguments are address of start of call sequence that called 257 // Arguments are address of start of call sequence that called
258 // the IC, 258 // the IC,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); 344 __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
345 } 345 }
346 346
347 347
348 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 348 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
349 // ----------- S t a t e ------------- 349 // ----------- S t a t e -------------
350 // -- rsp[0] : return address 350 // -- rsp[0] : return address
351 // -- rsp[8] : name 351 // -- rsp[8] : name
352 // -- rsp[16] : receiver 352 // -- rsp[16] : receiver
353 // ----------------------------------- 353 // -----------------------------------
354 Label slow, check_string, index_smi, index_string; 354 Label slow, check_string, index_int, index_string;
355 Label check_pixel_array, probe_dictionary; 355 Label check_pixel_array, probe_dictionary;
356 Label check_number_dictionary; 356 Label check_number_dictionary;
357 357
358 // Load name and receiver. 358 // Load name and receiver.
359 __ movq(rax, Operand(rsp, kPointerSize)); 359 __ movq(rax, Operand(rsp, kPointerSize));
360 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); 360 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
361 361
362 // Check that the object isn't a smi. 362 // Check that the object isn't a smi.
363 __ JumpIfSmi(rcx, &slow); 363 __ JumpIfSmi(rcx, &slow);
364 364
365 // Check that the object is some kind of JS object EXCEPT JS Value type. 365 // Check that the object is some kind of JS object EXCEPT JS Value type.
366 // In the case that the object is a value-wrapper object, 366 // In the case that the object is a value-wrapper object,
367 // we enter the runtime system to make sure that indexing 367 // we enter the runtime system to make sure that indexing
368 // into string objects work as intended. 368 // into string objects work as intended.
369 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 369 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
370 __ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx); 370 __ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx);
371 __ j(below, &slow); 371 __ j(below, &slow);
372 372
373 // Check bit field. 373 // Check bit field.
374 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 374 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
375 Immediate(kSlowCaseBitFieldMask)); 375 Immediate(kSlowCaseBitFieldMask));
376 __ j(not_zero, &slow); 376 __ j(not_zero, &slow);
377 377
378 // Check that the key is a smi. 378 // Check that the key is a smi.
379 __ JumpIfNotSmi(rax, &check_string); 379 __ JumpIfNotSmi(rax, &check_string);
380 380 // Save key in rbx in case we want it for the number dictionary
381 // case.
382 __ movq(rbx, rax);
383 __ SmiToInteger32(rax, rax);
381 // Get the elements array of the object. 384 // Get the elements array of the object.
382 __ bind(&index_smi); 385 __ bind(&index_int);
383 __ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset)); 386 __ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset));
384 // Check that the object is in fast mode (not dictionary). 387 // Check that the object is in fast mode (not dictionary).
385 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 388 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
386 Heap::kFixedArrayMapRootIndex); 389 Heap::kFixedArrayMapRootIndex);
387 __ j(not_equal, &check_pixel_array); 390 __ j(not_equal, &check_pixel_array);
388 // Check that the key (index) is within bounds. 391 // Check that the key (index) is within bounds.
389 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); 392 __ cmpl(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
390 __ j(above_equal, &slow); // Unsigned comparison rejects negative indices. 393 __ j(above_equal, &slow); // Unsigned comparison rejects negative indices.
391 // Fast case: Do the load. 394 // Fast case: Do the load.
392 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2); 395 __ movq(rax, Operand(rcx, rax, times_pointer_size,
393 __ movq(rax, FieldOperand(rcx, 396 FixedArray::kHeaderSize - kHeapObjectTag));
394 index.reg,
395 index.scale,
396 FixedArray::kHeaderSize));
397 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 397 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
398 // In case the loaded value is the_hole we have to consult GetProperty 398 // In case the loaded value is the_hole we have to consult GetProperty
399 // to ensure the prototype chain is searched. 399 // to ensure the prototype chain is searched.
400 __ j(equal, &slow); 400 __ j(equal, &slow);
401 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1); 401 __ IncrementCounter(&Counters::keyed_load_generic_smi, 1);
402 __ ret(0); 402 __ ret(0);
403 403
404 // Check whether the elements is a pixel array. 404 // Check whether the elements is a pixel array.
405 // rax: key 405 // rax: untagged index
406 // rcx: elements array 406 // rcx: elements array
407 __ bind(&check_pixel_array); 407 __ bind(&check_pixel_array);
408 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 408 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
409 Heap::kPixelArrayMapRootIndex); 409 Heap::kPixelArrayMapRootIndex);
410 __ j(not_equal, &check_number_dictionary); 410 __ j(not_equal, &check_number_dictionary);
411 __ SmiToInteger32(rax, rax);
412 __ cmpl(rax, FieldOperand(rcx, PixelArray::kLengthOffset)); 411 __ cmpl(rax, FieldOperand(rcx, PixelArray::kLengthOffset));
413 __ j(above_equal, &slow); 412 __ j(above_equal, &slow);
414 __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset)); 413 __ movq(rcx, FieldOperand(rcx, PixelArray::kExternalPointerOffset));
415 __ movzxbq(rax, Operand(rcx, rax, times_1, 0)); 414 __ movzxbq(rax, Operand(rcx, rax, times_1, 0));
416 __ Integer32ToSmi(rax, rax); 415 __ Integer32ToSmi(rax, rax);
417 __ ret(0); 416 __ ret(0);
418 417
419 __ bind(&check_number_dictionary); 418 __ bind(&check_number_dictionary);
420 // Check whether the elements is a number dictionary. 419 // Check whether the elements is a number dictionary.
421 // rax: key 420 // rax: untagged index
421 // rbx: key
422 // rcx: elements 422 // rcx: elements
423 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 423 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
424 Heap::kHashTableMapRootIndex); 424 Heap::kHashTableMapRootIndex);
425 __ j(not_equal, &slow); 425 __ j(not_equal, &slow);
426 __ SmiToInteger32(rbx, rax); 426 GenerateNumberDictionaryLoad(masm, &slow, rcx, rbx, rax, rdx, rdi);
427 GenerateNumberDictionaryLoad(masm, &slow, rcx, rax, rbx, rdx, rdi);
428 __ ret(0); 427 __ ret(0);
429 428
430 // Slow case: Load name and receiver from stack and jump to runtime. 429 // Slow case: Load name and receiver from stack and jump to runtime.
431 __ bind(&slow); 430 __ bind(&slow);
432 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); 431 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1);
433 GenerateRuntimeGetProperty(masm); 432 GenerateRuntimeGetProperty(masm);
434 __ bind(&check_string); 433 __ bind(&check_string);
435 // The key is not a smi. 434 // The key is not a smi.
436 // Is it a string? 435 // Is it a string?
437 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx); 436 __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdx);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 __ movq(rax, rcx); 505 __ movq(rax, rcx);
507 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 506 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
508 __ ret(0); 507 __ ret(0);
509 // If the hash field contains an array index pick it out. The assert checks 508 // If the hash field contains an array index pick it out. The assert checks
510 // that the constants for the maximum number of digits for an array index 509 // that the constants for the maximum number of digits for an array index
511 // cached in the hash field and the number of bits reserved for it does not 510 // cached in the hash field and the number of bits reserved for it does not
512 // conflict. 511 // conflict.
513 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 512 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
514 (1 << String::kArrayIndexValueBits)); 513 (1 << String::kArrayIndexValueBits));
515 __ bind(&index_string); 514 __ bind(&index_string);
516 // We want the smi-tagged index in rax. 515 __ movl(rax, rbx);
517 __ and_(rbx, Immediate(String::kArrayIndexValueMask)); 516 __ and_(rax, Immediate(String::kArrayIndexHashMask));
518 __ shr(rbx, Immediate(String::kHashShift)); 517 __ shrl(rax, Immediate(String::kHashShift));
519 __ Integer32ToSmi(rax, rbx); 518 __ jmp(&index_int);
520 __ jmp(&index_smi);
521 } 519 }
522 520
523 521
524 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 522 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
525 // ----------- S t a t e ------------- 523 // ----------- S t a t e -------------
526 // -- rsp[0] : return address 524 // -- rsp[0] : return address
527 // -- rsp[8] : name 525 // -- rsp[8] : name
528 // -- rsp[16] : receiver 526 // -- rsp[16] : receiver
529 // ----------------------------------- 527 // -----------------------------------
530 Label miss; 528 Label miss;
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 845
848 // Object case: Check key against length in the elements array. 846 // Object case: Check key against length in the elements array.
849 // rax: value 847 // rax: value
850 // rdx: JSObject 848 // rdx: JSObject
851 // rcx: index (as a smi) 849 // rcx: index (as a smi)
852 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 850 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
853 // Check that the object is in fast mode (not dictionary). 851 // Check that the object is in fast mode (not dictionary).
854 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 852 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
855 Heap::kFixedArrayMapRootIndex); 853 Heap::kFixedArrayMapRootIndex);
856 __ j(not_equal, &check_pixel_array); 854 __ j(not_equal, &check_pixel_array);
857 __ SmiCompare(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); 855 // Untag the key (for checking against untagged length in the fixed array).
856 __ SmiToInteger32(rdi, rcx);
857 __ cmpl(rdi, FieldOperand(rbx, Array::kLengthOffset));
858 // rax: value 858 // rax: value
859 // rbx: FixedArray 859 // rbx: FixedArray
860 // rcx: index (as a smi) 860 // rcx: index (as a smi)
861 __ j(below, &fast); 861 __ j(below, &fast);
862 862
863 // Slow case: call runtime. 863 // Slow case: call runtime.
864 __ bind(&slow); 864 __ bind(&slow);
865 GenerateRuntimeSetProperty(masm); 865 GenerateRuntimeSetProperty(masm);
866 866
867 // Check whether the elements is a pixel array. 867 // Check whether the elements is a pixel array.
(...skipping 28 matching lines...) Expand all
896 // Extra capacity case: Check if there is extra capacity to 896 // Extra capacity case: Check if there is extra capacity to
897 // perform the store and update the length. Used for adding one 897 // perform the store and update the length. Used for adding one
898 // element to the array by writing to array[array.length]. 898 // element to the array by writing to array[array.length].
899 __ bind(&extra); 899 __ bind(&extra);
900 // rax: value 900 // rax: value
901 // rdx: receiver (a JSArray) 901 // rdx: receiver (a JSArray)
902 // rbx: receiver's elements array (a FixedArray) 902 // rbx: receiver's elements array (a FixedArray)
903 // rcx: index (as a smi) 903 // rcx: index (as a smi)
904 // flags: smicompare (rdx.length(), rbx) 904 // flags: smicompare (rdx.length(), rbx)
905 __ j(not_equal, &slow); // do not leave holes in the array 905 __ j(not_equal, &slow); // do not leave holes in the array
906 __ SmiCompare(rcx, FieldOperand(rbx, FixedArray::kLengthOffset)); 906 __ SmiToInteger64(rdi, rcx);
907 __ cmpl(rdi, FieldOperand(rbx, FixedArray::kLengthOffset));
907 __ j(above_equal, &slow); 908 __ j(above_equal, &slow);
908 // Increment index to get new length. 909 // Increment and restore smi-tag.
909 __ SmiAddConstant(rdi, rcx, Smi::FromInt(1)); 910 __ Integer64PlusConstantToSmi(rdi, rdi, 1);
910 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rdi); 911 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
911 __ jmp(&fast); 912 __ jmp(&fast);
912 913
913 // Array case: Get the length and the elements array from the JS 914 // Array case: Get the length and the elements array from the JS
914 // array. Check that the array is in fast mode; if it is the 915 // array. Check that the array is in fast mode; if it is the
915 // length is always a smi. 916 // length is always a smi.
916 __ bind(&array); 917 __ bind(&array);
917 // rax: value 918 // rax: value
918 // rdx: receiver (a JSArray) 919 // rdx: receiver (a JSArray)
919 // rcx: index (as a smi) 920 // rcx: index (as a smi)
920 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 921 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
921 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 922 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
922 Heap::kFixedArrayMapRootIndex); 923 Heap::kFixedArrayMapRootIndex);
923 __ j(not_equal, &slow); 924 __ j(not_equal, &slow);
924 925
925 // Check the key against the length in the array, compute the 926 // Check the key against the length in the array, compute the
926 // address to store into and fall through to fast case. 927 // address to store into and fall through to fast case.
927 __ SmiCompare(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 928 __ SmiCompare(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
928 __ j(below_equal, &extra); 929 __ j(below_equal, &extra);
929 930
930 // Fast case: Do the store. 931 // Fast case: Do the store.
931 __ bind(&fast); 932 __ bind(&fast);
932 // rax: value 933 // rax: value
933 // rbx: receiver's elements array (a FixedArray) 934 // rbx: receiver's elements array (a FixedArray)
934 // rcx: index (as a smi) 935 // rcx: index (as a smi)
935 Label non_smi_value; 936 Label non_smi_value;
936 __ JumpIfNotSmi(rax, &non_smi_value); 937 __ JumpIfNotSmi(rax, &non_smi_value);
937 SmiIndex index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2); 938 SmiIndex index = masm->SmiToIndex(rcx, rcx, kPointerSizeLog2);
938 __ movq(FieldOperand(rbx, index.reg, index.scale, FixedArray::kHeaderSize), 939 __ movq(Operand(rbx, index.reg, index.scale,
940 FixedArray::kHeaderSize - kHeapObjectTag),
939 rax); 941 rax);
940 __ ret(0); 942 __ ret(0);
941 __ bind(&non_smi_value); 943 __ bind(&non_smi_value);
942 // Slow case that needs to retain rcx for use by RecordWrite. 944 // Slow case that needs to retain rcx for use by RecordWrite.
943 // Update write barrier for the elements array address. 945 // Update write barrier for the elements array address.
944 SmiIndex index2 = masm->SmiToIndex(kScratchRegister, rcx, kPointerSizeLog2); 946 SmiIndex index2 = masm->SmiToIndex(kScratchRegister, rcx, kPointerSizeLog2);
945 __ movq(FieldOperand(rbx, index2.reg, index2.scale, FixedArray::kHeaderSize), 947 __ movq(Operand(rbx, index2.reg, index2.scale,
948 FixedArray::kHeaderSize - kHeapObjectTag),
946 rax); 949 rax);
947 __ movq(rdx, rax); 950 __ movq(rdx, rax);
948 __ RecordWriteNonSmi(rbx, 0, rdx, rcx); 951 __ RecordWriteNonSmi(rbx, 0, rdx, rcx);
949 __ ret(0); 952 __ ret(0);
950 } 953 }
951 954
952 955
953 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, 956 void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
954 ExternalArrayType array_type) { 957 ExternalArrayType array_type) {
955 // ----------- S t a t e ------------- 958 // ----------- S t a t e -------------
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 GenerateMiss(masm); 1616 GenerateMiss(masm);
1614 } 1617 }
1615 1618
1616 1619
1617 #undef __ 1620 #undef __
1618 1621
1619 1622
1620 } } // namespace v8::internal 1623 } } // namespace v8::internal
1621 1624
1622 #endif // V8_TARGET_ARCH_X64 1625 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698