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

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

Issue 196139: X64: Convert smis to holding 32 bits of payload. (Closed)
Patch Set: Addressed review comments. Forwarded to head. Created 11 years, 2 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
« no previous file with comments | « src/x64/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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 if (i != kProbes - 1) { 124 if (i != kProbes - 1) {
125 __ j(equal, &done); 125 __ j(equal, &done);
126 } else { 126 } else {
127 __ j(not_equal, miss_label); 127 __ j(not_equal, miss_label);
128 } 128 }
129 } 129 }
130 130
131 // Check that the value is a normal property. 131 // Check that the value is a normal property.
132 __ bind(&done); 132 __ bind(&done);
133 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 133 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
134 __ testl(Operand(r0, r1, times_pointer_size, kDetailsOffset - kHeapObjectTag), 134 __ Test(Operand(r0, r1, times_pointer_size, kDetailsOffset - kHeapObjectTag),
135 Immediate(Smi::FromInt(PropertyDetails::TypeField::mask()))); 135 Smi::FromInt(PropertyDetails::TypeField::mask()));
136 __ j(not_zero, miss_label); 136 __ j(not_zero, miss_label);
137 137
138 // Get the value at the masked, scaled index. 138 // Get the value at the masked, scaled index.
139 const int kValueOffset = kElementsStartOffset + kPointerSize; 139 const int kValueOffset = kElementsStartOffset + kPointerSize;
140 __ movq(r1, 140 __ movq(r1,
141 Operand(r0, r1, times_pointer_size, kValueOffset - kHeapObjectTag)); 141 Operand(r0, r1, times_pointer_size, kValueOffset - kHeapObjectTag));
142 } 142 }
143 143
144 144
145 // Helper function used to check that a value is either not an object 145 // Helper function used to check that a value is either not an object
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 // Is the string an array index, with cached numeric value? 329 // Is the string an array index, with cached numeric value?
330 __ movl(rbx, FieldOperand(rax, String::kLengthOffset)); 330 __ movl(rbx, FieldOperand(rax, String::kLengthOffset));
331 __ testl(rbx, Immediate(String::kIsArrayIndexMask)); 331 __ testl(rbx, Immediate(String::kIsArrayIndexMask));
332 332
333 // If the string is a symbol, do a quick inline probe of the receiver's 333 // If the string is a symbol, do a quick inline probe of the receiver's
334 // dictionary, if it exists. 334 // dictionary, if it exists.
335 __ j(not_zero, &index_string); // The value in rbx is used at jump target. 335 __ j(not_zero, &index_string); // The value in rbx is used at jump target.
336 __ testb(FieldOperand(rdx, Map::kInstanceTypeOffset), 336 __ testb(FieldOperand(rdx, Map::kInstanceTypeOffset),
337 Immediate(kIsSymbolMask)); 337 Immediate(kIsSymbolMask));
338 __ j(zero, &slow); 338 __ j(zero, &slow);
339 // Probe the dictionary leaving result in ecx. 339 // Probe the dictionary leaving result in rcx.
340 GenerateDictionaryLoad(masm, &slow, rbx, rcx, rdx, rax); 340 GenerateDictionaryLoad(masm, &slow, rbx, rcx, rdx, rax);
341 GenerateCheckNonObjectOrLoaded(masm, &slow, rcx); 341 GenerateCheckNonObjectOrLoaded(masm, &slow, rcx);
342 __ movq(rax, rcx); 342 __ movq(rax, rcx);
343 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); 343 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
344 __ ret(0); 344 __ ret(0);
345 // Array index string: If short enough use cache in length/hash field (ebx). 345 // Array index string: If short enough use cache in length/hash field (rbx).
346 // We assert that there are enough bits in an int32_t after the hash shift 346 // We assert that there are enough bits in an int32_t after the hash shift
347 // bits have been subtracted to allow space for the length and the cached 347 // bits have been subtracted to allow space for the length and the cached
348 // array index. 348 // array index.
349 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < 349 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
350 (1 << (String::kShortLengthShift - String::kHashShift))); 350 (1 << (String::kShortLengthShift - String::kHashShift)));
351 __ bind(&index_string); 351 __ bind(&index_string);
352 const int kLengthFieldLimit = 352 const int kLengthFieldLimit =
353 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift; 353 (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift;
354 __ cmpl(rbx, Immediate(kLengthFieldLimit)); 354 __ cmpl(rbx, Immediate(kLengthFieldLimit));
355 __ j(above_equal, &slow); 355 __ j(above_equal, &slow);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 427 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
428 // Check that the receiver does not require access checks. We need 428 // Check that the receiver does not require access checks. We need
429 // to do this because this generic stub does not perform map checks. 429 // to do this because this generic stub does not perform map checks.
430 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 430 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
431 Immediate(1 << Map::kIsAccessCheckNeeded)); 431 Immediate(1 << Map::kIsAccessCheckNeeded));
432 __ j(not_zero, &slow); 432 __ j(not_zero, &slow);
433 // Get the key from the stack. 433 // Get the key from the stack.
434 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); // 1 ~ return address 434 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); // 1 ~ return address
435 // Check that the key is a smi. 435 // Check that the key is a smi.
436 __ JumpIfNotSmi(rbx, &slow); 436 __ JumpIfNotSmi(rbx, &slow);
437 // If it is a smi, make sure it is zero-extended, so it can be
438 // used as an index in a memory operand.
439 __ movl(rbx, rbx); // Clear the high bits of rbx.
440 437
441 __ CmpInstanceType(rcx, JS_ARRAY_TYPE); 438 __ CmpInstanceType(rcx, JS_ARRAY_TYPE);
442 __ j(equal, &array); 439 __ j(equal, &array);
443 // Check that the object is some kind of JS object. 440 // Check that the object is some kind of JS object.
444 __ CmpInstanceType(rcx, FIRST_JS_OBJECT_TYPE); 441 __ CmpInstanceType(rcx, FIRST_JS_OBJECT_TYPE);
445 __ j(below, &slow); 442 __ j(below, &slow);
446 443
447 // Object case: Check key against length in the elements array. 444 // Object case: Check key against length in the elements array.
448 // rax: value 445 // rax: value
449 // rdx: JSObject 446 // rdx: JSObject
450 // rbx: index (as a smi), zero-extended. 447 // rbx: index (as a smi)
451 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 448 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
452 // Check that the object is in fast mode (not dictionary). 449 // Check that the object is in fast mode (not dictionary).
453 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 450 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
454 Heap::kFixedArrayMapRootIndex); 451 Heap::kFixedArrayMapRootIndex);
455 __ j(not_equal, &check_pixel_array); 452 __ j(not_equal, &check_pixel_array);
456 // Untag the key (for checking against untagged length in the fixed array). 453 // Untag the key (for checking against untagged length in the fixed array).
457 __ SmiToInteger32(rdx, rbx); 454 __ SmiToInteger32(rdx, rbx);
458 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset)); 455 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset));
459 // rax: value 456 // rax: value
460 // rcx: FixedArray 457 // rcx: FixedArray
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 __ ret(0); 498 __ ret(0);
502 499
503 // Extra capacity case: Check if there is extra capacity to 500 // Extra capacity case: Check if there is extra capacity to
504 // perform the store and update the length. Used for adding one 501 // perform the store and update the length. Used for adding one
505 // element to the array by writing to array[array.length]. 502 // element to the array by writing to array[array.length].
506 __ bind(&extra); 503 __ bind(&extra);
507 // rax: value 504 // rax: value
508 // rdx: JSArray 505 // rdx: JSArray
509 // rcx: FixedArray 506 // rcx: FixedArray
510 // rbx: index (as a smi) 507 // rbx: index (as a smi)
511 // flags: compare (rbx, rdx.length()) 508 // flags: smicompare (rdx.length(), rbx)
512 __ j(not_equal, &slow); // do not leave holes in the array 509 __ j(not_equal, &slow); // do not leave holes in the array
513 __ SmiToInteger64(rbx, rbx); 510 __ SmiToInteger64(rbx, rbx);
514 __ cmpl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); 511 __ cmpl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
515 __ j(above_equal, &slow); 512 __ j(above_equal, &slow);
516 // Increment and restore smi-tag. 513 // Increment and restore smi-tag.
517 __ Integer64AddToSmi(rbx, rbx, 1); 514 __ Integer64PlusConstantToSmi(rbx, rbx, 1);
518 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rbx); 515 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rbx);
519 __ SmiSubConstant(rbx, rbx, 1, NULL); 516 __ SmiSubConstant(rbx, rbx, Smi::FromInt(1));
520 __ jmp(&fast); 517 __ jmp(&fast);
521 518
522 // Array case: Get the length and the elements array from the JS 519 // Array case: Get the length and the elements array from the JS
523 // array. Check that the array is in fast mode; if it is the 520 // array. Check that the array is in fast mode; if it is the
524 // length is always a smi. 521 // length is always a smi.
525 __ bind(&array); 522 __ bind(&array);
526 // rax: value 523 // rax: value
527 // rdx: JSArray 524 // rdx: JSArray
528 // rbx: index (as a smi) 525 // rbx: index (as a smi)
529 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 526 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
530 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map()); 527 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
528 Heap::kFixedArrayMapRootIndex);
531 __ j(not_equal, &slow); 529 __ j(not_equal, &slow);
532 530
533 // Check the key against the length in the array, compute the 531 // Check the key against the length in the array, compute the
534 // address to store into and fall through to fast case. 532 // address to store into and fall through to fast case.
535 __ cmpl(rbx, FieldOperand(rdx, JSArray::kLengthOffset)); 533 __ SmiCompare(FieldOperand(rdx, JSArray::kLengthOffset), rbx);
536 __ j(above_equal, &extra); 534 __ j(below_equal, &extra);
537 535
538 // Fast case: Do the store. 536 // Fast case: Do the store.
539 __ bind(&fast); 537 __ bind(&fast);
540 // rax: value 538 // rax: value
541 // rcx: FixedArray 539 // rcx: FixedArray
542 // rbx: index (as a smi) 540 // rbx: index (as a smi)
543 __ movq(Operand(rcx, rbx, times_half_pointer_size, 541 Label non_smi_value;
542 __ JumpIfNotSmi(rax, &non_smi_value);
543 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
544 __ movq(Operand(rcx, index.reg, index.scale,
544 FixedArray::kHeaderSize - kHeapObjectTag), 545 FixedArray::kHeaderSize - kHeapObjectTag),
545 rax); 546 rax);
547 __ ret(0);
548 __ bind(&non_smi_value);
549 // Slow case that needs to retain rbx for use by RecordWrite.
546 // Update write barrier for the elements array address. 550 // Update write barrier for the elements array address.
551 SmiIndex index2 = masm->SmiToIndex(kScratchRegister, rbx, kPointerSizeLog2);
552 __ movq(Operand(rcx, index2.reg, index2.scale,
553 FixedArray::kHeaderSize - kHeapObjectTag),
554 rax);
547 __ movq(rdx, rax); 555 __ movq(rdx, rax);
548 __ RecordWrite(rcx, 0, rdx, rbx); 556 __ RecordWriteNonSmi(rcx, 0, rdx, rbx);
549 __ ret(0); 557 __ ret(0);
550 } 558 }
551 559
552 560
553 void CallIC::Generate(MacroAssembler* masm, 561 void CallIC::Generate(MacroAssembler* masm,
554 int argc, 562 int argc,
555 ExternalReference const& f) { 563 ExternalReference const& f) {
556 // Get the receiver of the function from the stack; 1 ~ return address. 564 // Get the receiver of the function from the stack; 1 ~ return address.
557 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 565 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
558 // Get the name of the function to call from the stack. 566 // Get the name of the function to call from the stack.
(...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 1017
1010 // Cache miss: Jump to runtime. 1018 // Cache miss: Jump to runtime.
1011 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss))); 1019 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
1012 } 1020 }
1013 1021
1014 1022
1015 #undef __ 1023 #undef __
1016 1024
1017 1025
1018 } } // namespace v8::internal 1026 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/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