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

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

Issue 196077: X64: Extract all smi operations into MacroAssembler macros. (Closed)
Patch Set: Created 11 years, 3 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
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // Check that the properties array is a dictionary. 88 // Check that the properties array is a dictionary.
89 __ movq(r0, FieldOperand(r1, JSObject::kPropertiesOffset)); 89 __ movq(r0, FieldOperand(r1, JSObject::kPropertiesOffset));
90 __ Cmp(FieldOperand(r0, HeapObject::kMapOffset), Factory::hash_table_map()); 90 __ Cmp(FieldOperand(r0, HeapObject::kMapOffset), Factory::hash_table_map());
91 __ j(not_equal, miss_label); 91 __ j(not_equal, miss_label);
92 92
93 // Compute the capacity mask. 93 // Compute the capacity mask.
94 const int kCapacityOffset = 94 const int kCapacityOffset =
95 StringDictionary::kHeaderSize + 95 StringDictionary::kHeaderSize +
96 StringDictionary::kCapacityIndex * kPointerSize; 96 StringDictionary::kCapacityIndex * kPointerSize;
97 __ movq(r2, FieldOperand(r0, kCapacityOffset)); 97 __ movq(r2, FieldOperand(r0, kCapacityOffset));
98 __ shrl(r2, Immediate(kSmiTagSize)); // convert smi to int 98 __ SmiToInteger32(r2, r2);
99 __ decl(r2); 99 __ decl(r2);
100 100
101 // Generate an unrolled loop that performs a few probes before 101 // Generate an unrolled loop that performs a few probes before
102 // giving up. Measurements done on Gmail indicate that 2 probes 102 // giving up. Measurements done on Gmail indicate that 2 probes
103 // cover ~93% of loads from dictionaries. 103 // cover ~93% of loads from dictionaries.
104 static const int kProbes = 4; 104 static const int kProbes = 4;
105 const int kElementsStartOffset = 105 const int kElementsStartOffset =
106 StringDictionary::kHeaderSize + 106 StringDictionary::kHeaderSize +
107 StringDictionary::kElementsStartIndex * kPointerSize; 107 StringDictionary::kElementsStartIndex * kPointerSize;
108 for (int i = 0; i < kProbes; i++) { 108 for (int i = 0; i < kProbes; i++) {
(...skipping 16 matching lines...) Expand all
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 __ testl(Operand(r0, r1, times_pointer_size, kDetailsOffset - kHeapObjectTag),
135 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); 135 Immediate(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
146 // or is loaded if it is an object. 146 // or is loaded if it is an object.
147 static void GenerateCheckNonObjectOrLoaded(MacroAssembler* masm, Label* miss, 147 static void GenerateCheckNonObjectOrLoaded(MacroAssembler* masm, Label* miss,
148 Register value) { 148 Register value) {
149 Label done; 149 Label done;
150 // Check if the value is a Smi. 150 // Check if the value is a Smi.
151 __ testl(value, Immediate(kSmiTagMask)); 151 __ JumpIfSmi(value, &done);
152 __ j(zero, &done);
153 // Check if the object has been loaded. 152 // Check if the object has been loaded.
154 __ movq(kScratchRegister, FieldOperand(value, JSFunction::kMapOffset)); 153 __ movq(kScratchRegister, FieldOperand(value, JSFunction::kMapOffset));
155 __ testb(FieldOperand(kScratchRegister, Map::kBitField2Offset), 154 __ testb(FieldOperand(kScratchRegister, Map::kBitField2Offset),
156 Immediate(1 << Map::kNeedsLoading)); 155 Immediate(1 << Map::kNeedsLoading));
157 __ j(not_zero, miss); 156 __ j(not_zero, miss);
158 __ bind(&done); 157 __ bind(&done);
159 } 158 }
160 159
161 160
162 // One byte opcode for test eax,0xXXXXXXXX. 161 // One byte opcode for test eax,0xXXXXXXXX.
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 // -- rsp[8] : name 257 // -- rsp[8] : name
259 // -- rsp[16] : receiver 258 // -- rsp[16] : receiver
260 // ----------------------------------- 259 // -----------------------------------
261 Label slow, fast, check_string, index_int, index_string; 260 Label slow, fast, check_string, index_int, index_string;
262 261
263 // Load name and receiver. 262 // Load name and receiver.
264 __ movq(rax, Operand(rsp, kPointerSize)); 263 __ movq(rax, Operand(rsp, kPointerSize));
265 __ movq(rcx, Operand(rsp, 2 * kPointerSize)); 264 __ movq(rcx, Operand(rsp, 2 * kPointerSize));
266 265
267 // Check that the object isn't a smi. 266 // Check that the object isn't a smi.
268 __ testl(rcx, Immediate(kSmiTagMask)); 267 __ JumpIfSmi(rcx, &slow);
269 __ j(zero, &slow);
270 268
271 // Check that the object is some kind of JS object EXCEPT JS Value type. 269 // Check that the object is some kind of JS object EXCEPT JS Value type.
272 // In the case that the object is a value-wrapper object, 270 // In the case that the object is a value-wrapper object,
273 // we enter the runtime system to make sure that indexing 271 // we enter the runtime system to make sure that indexing
274 // into string objects work as intended. 272 // into string objects work as intended.
275 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); 273 ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE);
276 __ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx); 274 __ CmpObjectType(rcx, JS_OBJECT_TYPE, rdx);
277 __ j(below, &slow); 275 __ j(below, &slow);
278 // Check that the receiver does not require access checks. We need 276 // Check that the receiver does not require access checks. We need
279 // to check this explicitly since this generic stub does not perform 277 // to check this explicitly since this generic stub does not perform
280 // map checks. The map is already in rdx. 278 // map checks. The map is already in rdx.
281 __ testb(FieldOperand(rdx, Map::kBitFieldOffset), 279 __ testb(FieldOperand(rdx, Map::kBitFieldOffset),
282 Immediate(1 << Map::kIsAccessCheckNeeded)); 280 Immediate(1 << Map::kIsAccessCheckNeeded));
283 __ j(not_zero, &slow); 281 __ j(not_zero, &slow);
284 282
285 // Check that the key is a smi. 283 // Check that the key is a smi.
286 __ testl(rax, Immediate(kSmiTagMask)); 284 __ JumpIfNotSmi(rax, &check_string);
287 __ j(not_zero, &check_string); 285 __ SmiToInteger32(rax, rax);
288 __ sarl(rax, Immediate(kSmiTagSize));
289 // Get the elements array of the object. 286 // Get the elements array of the object.
290 __ bind(&index_int); 287 __ bind(&index_int);
291 __ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset)); 288 __ movq(rcx, FieldOperand(rcx, JSObject::kElementsOffset));
292 // Check that the object is in fast mode (not dictionary). 289 // Check that the object is in fast mode (not dictionary).
293 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map()); 290 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map());
294 __ j(not_equal, &slow); 291 __ j(not_equal, &slow);
295 // Check that the key (index) is within bounds. 292 // Check that the key (index) is within bounds.
296 __ cmpl(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); 293 __ cmpl(rax, FieldOperand(rcx, FixedArray::kLengthOffset));
297 __ j(below, &fast); // Unsigned comparison rejects negative indices. 294 __ j(below, &fast); // Unsigned comparison rejects negative indices.
298 // Slow case: Load name and receiver from stack and jump to runtime. 295 // Slow case: Load name and receiver from stack and jump to runtime.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 // -- rax : value 400 // -- rax : value
404 // -- rsp[0] : return address 401 // -- rsp[0] : return address
405 // -- rsp[8] : key 402 // -- rsp[8] : key
406 // -- rsp[16] : receiver 403 // -- rsp[16] : receiver
407 // ----------------------------------- 404 // -----------------------------------
408 Label slow, fast, array, extra; 405 Label slow, fast, array, extra;
409 406
410 // Get the receiver from the stack. 407 // Get the receiver from the stack.
411 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // 2 ~ return address, key 408 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // 2 ~ return address, key
412 // Check that the object isn't a smi. 409 // Check that the object isn't a smi.
413 __ testl(rdx, Immediate(kSmiTagMask)); 410 __ JumpIfSmi(rdx, &slow);
414 __ j(zero, &slow);
415 // Get the map from the receiver. 411 // Get the map from the receiver.
416 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 412 __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset));
417 // Check that the receiver does not require access checks. We need 413 // Check that the receiver does not require access checks. We need
418 // to do this because this generic stub does not perform map checks. 414 // to do this because this generic stub does not perform map checks.
419 __ testb(FieldOperand(rcx, Map::kBitFieldOffset), 415 __ testb(FieldOperand(rcx, Map::kBitFieldOffset),
420 Immediate(1 << Map::kIsAccessCheckNeeded)); 416 Immediate(1 << Map::kIsAccessCheckNeeded));
421 __ j(not_zero, &slow); 417 __ j(not_zero, &slow);
422 // Get the key from the stack. 418 // Get the key from the stack.
423 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); // 1 ~ return address 419 __ movq(rbx, Operand(rsp, 1 * kPointerSize)); // 1 ~ return address
424 // Check that the key is a smi. 420 // Check that the key is a smi.
425 __ testl(rbx, Immediate(kSmiTagMask)); 421 __ JumpIfNotSmi(rbx, &slow);
426 __ j(not_zero, &slow);
427 // If it is a smi, make sure it is zero-extended, so it can be 422 // If it is a smi, make sure it is zero-extended, so it can be
428 // used as an index in a memory operand. 423 // used as an index in a memory operand.
429 __ movl(rbx, rbx); // Clear the high bits of rbx. 424 __ movl(rbx, rbx); // Clear the high bits of rbx.
430 425
431 __ CmpInstanceType(rcx, JS_ARRAY_TYPE); 426 __ CmpInstanceType(rcx, JS_ARRAY_TYPE);
432 __ j(equal, &array); 427 __ j(equal, &array);
433 // Check that the object is some kind of JS object. 428 // Check that the object is some kind of JS object.
434 __ CmpInstanceType(rcx, FIRST_JS_OBJECT_TYPE); 429 __ CmpInstanceType(rcx, FIRST_JS_OBJECT_TYPE);
435 __ j(below, &slow); 430 __ j(below, &slow);
436 431
437 // Object case: Check key against length in the elements array. 432 // Object case: Check key against length in the elements array.
438 // rax: value 433 // rax: value
439 // rdx: JSObject 434 // rdx: JSObject
440 // rbx: index (as a smi), zero-extended. 435 // rbx: index (as a smi), zero-extended.
441 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 436 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
442 // Check that the object is in fast mode (not dictionary). 437 // Check that the object is in fast mode (not dictionary).
443 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map()); 438 __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), Factory::fixed_array_map());
444 __ j(not_equal, &slow); 439 __ j(not_equal, &slow);
445 // Untag the key (for checking against untagged length in the fixed array). 440 // Untag the key (for checking against untagged length in the fixed array).
446 __ movl(rdx, rbx); 441 __ SmiToInteger32(rdx, rbx);
447 __ sarl(rdx, Immediate(kSmiTagSize));
448 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset)); 442 __ cmpl(rdx, FieldOperand(rcx, Array::kLengthOffset));
449 // rax: value 443 // rax: value
450 // rcx: FixedArray 444 // rcx: FixedArray
451 // rbx: index (as a smi) 445 // rbx: index (as a smi)
452 __ j(below, &fast); 446 __ j(below, &fast);
453 447
454 448
455 // Slow case: Push extra copies of the arguments (3). 449 // Slow case: Push extra copies of the arguments (3).
456 __ bind(&slow); 450 __ bind(&slow);
457 __ pop(rcx); 451 __ pop(rcx);
458 __ push(Operand(rsp, 1 * kPointerSize)); 452 __ push(Operand(rsp, 1 * kPointerSize));
459 __ push(Operand(rsp, 1 * kPointerSize)); 453 __ push(Operand(rsp, 1 * kPointerSize));
460 __ push(rax); 454 __ push(rax);
461 __ push(rcx); 455 __ push(rcx);
462 // Do tail-call to runtime routine. 456 // Do tail-call to runtime routine.
463 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1); 457 __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1);
464 458
465 459
466 // Extra capacity case: Check if there is extra capacity to 460 // Extra capacity case: Check if there is extra capacity to
467 // perform the store and update the length. Used for adding one 461 // perform the store and update the length. Used for adding one
468 // element to the array by writing to array[array.length]. 462 // element to the array by writing to array[array.length].
469 __ bind(&extra); 463 __ bind(&extra);
470 // rax: value 464 // rax: value
471 // rdx: JSArray 465 // rdx: JSArray
472 // rcx: FixedArray 466 // rcx: FixedArray
473 // rbx: index (as a smi) 467 // rbx: index (as a smi)
474 // flags: compare (rbx, rdx.length()) 468 // flags: compare (rbx, rdx.length())
475 __ j(not_equal, &slow); // do not leave holes in the array 469 __ j(not_equal, &slow); // do not leave holes in the array
476 __ sarl(rbx, Immediate(kSmiTagSize)); // untag 470 __ SmiToInteger64(rbx, rbx);
477 __ cmpl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); 471 __ cmpl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
478 __ j(above_equal, &slow); 472 __ j(above_equal, &slow);
479 // Restore tag and increment. 473 // Increment and restore smi-tag.
480 __ lea(rbx, Operand(rbx, rbx, times_1, 1 << kSmiTagSize)); 474 __ Integer64AddToSmi(rbx, rbx, 1);
481 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rbx); 475 __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rbx);
482 __ subl(rbx, Immediate(1 << kSmiTagSize)); // decrement rbx again 476 __ SmiSubConstant(rbx, rbx, 1, NULL);
483 __ jmp(&fast); 477 __ jmp(&fast);
484 478
485 479
486 // Array case: Get the length and the elements array from the JS 480 // Array case: Get the length and the elements array from the JS
487 // array. Check that the array is in fast mode; if it is the 481 // array. Check that the array is in fast mode; if it is the
488 // length is always a smi. 482 // length is always a smi.
489 __ bind(&array); 483 __ bind(&array);
490 // rax: value 484 // rax: value
491 // rdx: JSArray 485 // rdx: JSArray
492 // rbx: index (as a smi) 486 // rbx: index (as a smi)
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 __ movq(rbx, f); 531 __ movq(rbx, f);
538 __ CallStub(&stub); 532 __ CallStub(&stub);
539 533
540 // Move result to rdi and exit the internal frame. 534 // Move result to rdi and exit the internal frame.
541 __ movq(rdi, rax); 535 __ movq(rdi, rax);
542 __ LeaveInternalFrame(); 536 __ LeaveInternalFrame();
543 537
544 // Check if the receiver is a global object of some sort. 538 // Check if the receiver is a global object of some sort.
545 Label invoke, global; 539 Label invoke, global;
546 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); // receiver 540 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); // receiver
547 __ testl(rdx, Immediate(kSmiTagMask)); 541 __ JumpIfSmi(rdx, &invoke);
548 __ j(zero, &invoke);
549 __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx); 542 __ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
550 __ j(equal, &global); 543 __ j(equal, &global);
551 __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE); 544 __ CmpInstanceType(rcx, JS_BUILTINS_OBJECT_TYPE);
552 __ j(not_equal, &invoke); 545 __ j(not_equal, &invoke);
553 546
554 // Patch the receiver on the stack. 547 // Patch the receiver on the stack.
555 __ bind(&global); 548 __ bind(&global);
556 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 549 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
557 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); 550 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
558 551
(...skipping 28 matching lines...) Expand all
587 Code::Flags flags = 580 Code::Flags flags =
588 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc); 581 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc);
589 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, rax); 582 StubCache::GenerateProbe(masm, flags, rdx, rcx, rbx, rax);
590 583
591 // If the stub cache probing failed, the receiver might be a value. 584 // If the stub cache probing failed, the receiver might be a value.
592 // For value objects, we use the map of the prototype objects for 585 // For value objects, we use the map of the prototype objects for
593 // the corresponding JSValue for the cache and that is what we need 586 // the corresponding JSValue for the cache and that is what we need
594 // to probe. 587 // to probe.
595 // 588 //
596 // Check for number. 589 // Check for number.
597 __ testl(rdx, Immediate(kSmiTagMask)); 590 __ JumpIfSmi(rdx, &number);
598 __ j(zero, &number);
599 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rbx); 591 __ CmpObjectType(rdx, HEAP_NUMBER_TYPE, rbx);
600 __ j(not_equal, &non_number); 592 __ j(not_equal, &non_number);
601 __ bind(&number); 593 __ bind(&number);
602 StubCompiler::GenerateLoadGlobalFunctionPrototype( 594 StubCompiler::GenerateLoadGlobalFunctionPrototype(
603 masm, Context::NUMBER_FUNCTION_INDEX, rdx); 595 masm, Context::NUMBER_FUNCTION_INDEX, rdx);
604 __ jmp(&probe); 596 __ jmp(&probe);
605 597
606 // Check for string. 598 // Check for string.
607 __ bind(&non_number); 599 __ bind(&non_number);
608 __ CmpInstanceType(rbx, FIRST_NONSTRING_TYPE); 600 __ CmpInstanceType(rbx, FIRST_NONSTRING_TYPE);
(...skipping 24 matching lines...) Expand all
633 625
634 static void GenerateNormalHelper(MacroAssembler* masm, 626 static void GenerateNormalHelper(MacroAssembler* masm,
635 int argc, 627 int argc,
636 bool is_global_object, 628 bool is_global_object,
637 Label* miss) { 629 Label* miss) {
638 // Search dictionary - put result in register edx. 630 // Search dictionary - put result in register edx.
639 GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx); 631 GenerateDictionaryLoad(masm, miss, rax, rdx, rbx, rcx);
640 632
641 // Move the result to register rdi and check that it isn't a smi. 633 // Move the result to register rdi and check that it isn't a smi.
642 __ movq(rdi, rdx); 634 __ movq(rdi, rdx);
643 __ testl(rdx, Immediate(kSmiTagMask)); 635 __ JumpIfSmi(rdx, miss);
644 __ j(zero, miss);
645 636
646 // Check that the value is a JavaScript function. 637 // Check that the value is a JavaScript function.
647 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rdx); 638 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rdx);
648 __ j(not_equal, miss); 639 __ j(not_equal, miss);
649 // Check that the function has been loaded. 640 // Check that the function has been loaded.
650 __ testb(FieldOperand(rdx, Map::kBitField2Offset), 641 __ testb(FieldOperand(rdx, Map::kBitField2Offset),
651 Immediate(1 << Map::kNeedsLoading)); 642 Immediate(1 << Map::kNeedsLoading));
652 __ j(not_zero, miss); 643 __ j(not_zero, miss);
653 644
654 // Patch the receiver with the global proxy if necessary. 645 // Patch the receiver with the global proxy if necessary.
(...skipping 21 matching lines...) Expand all
676 // ----------------------------------- 667 // -----------------------------------
677 668
678 Label miss, global_object, non_global_object; 669 Label miss, global_object, non_global_object;
679 670
680 // Get the receiver of the function from the stack. 671 // Get the receiver of the function from the stack.
681 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 672 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
682 // Get the name of the function from the stack. 673 // Get the name of the function from the stack.
683 __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize)); 674 __ movq(rcx, Operand(rsp, (argc + 2) * kPointerSize));
684 675
685 // Check that the receiver isn't a smi. 676 // Check that the receiver isn't a smi.
686 __ testl(rdx, Immediate(kSmiTagMask)); 677 __ JumpIfSmi(rdx, &miss);
687 __ j(zero, &miss);
688 678
689 // Check that the receiver is a valid JS object. 679 // Check that the receiver is a valid JS object.
690 // Because there are so many map checks and type checks, do not 680 // Because there are so many map checks and type checks, do not
691 // use CmpObjectType, but load map and type into registers. 681 // use CmpObjectType, but load map and type into registers.
692 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 682 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
693 __ movb(rax, FieldOperand(rbx, Map::kInstanceTypeOffset)); 683 __ movb(rax, FieldOperand(rbx, Map::kInstanceTypeOffset));
694 __ cmpb(rax, Immediate(FIRST_JS_OBJECT_TYPE)); 684 __ cmpb(rax, Immediate(FIRST_JS_OBJECT_TYPE));
695 __ j(below, &miss); 685 __ j(below, &miss);
696 686
697 // If this assert fails, we have to check upper bound too. 687 // If this assert fails, we have to check upper bound too.
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 // -- rcx : name 827 // -- rcx : name
838 // -- rsp[0] : return address 828 // -- rsp[0] : return address
839 // -- rsp[8] : receiver 829 // -- rsp[8] : receiver
840 // ----------------------------------- 830 // -----------------------------------
841 831
842 Label miss, probe, global; 832 Label miss, probe, global;
843 833
844 __ movq(rax, Operand(rsp, kPointerSize)); 834 __ movq(rax, Operand(rsp, kPointerSize));
845 835
846 // Check that the receiver isn't a smi. 836 // Check that the receiver isn't a smi.
847 __ testl(rax, Immediate(kSmiTagMask)); 837 __ JumpIfSmi(rax, &miss);
848 __ j(zero, &miss);
849 838
850 // Check that the receiver is a valid JS object. 839 // Check that the receiver is a valid JS object.
851 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx); 840 __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
852 __ j(below, &miss); 841 __ j(below, &miss);
853 842
854 // If this assert fails, we have to check upper bound too. 843 // If this assert fails, we have to check upper bound too.
855 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 844 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
856 845
857 // Check for access to global object (unlikely). 846 // Check for access to global object (unlikely).
858 __ CmpInstanceType(rbx, JS_GLOBAL_PROXY_TYPE); 847 __ CmpInstanceType(rbx, JS_GLOBAL_PROXY_TYPE);
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 968
980 // Cache miss: Jump to runtime. 969 // Cache miss: Jump to runtime.
981 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss))); 970 Generate(masm, ExternalReference(IC_Utility(kStoreIC_Miss)));
982 } 971 }
983 972
984 973
985 #undef __ 974 #undef __
986 975
987 976
988 } } // namespace v8::internal 977 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698