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

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

Issue 2071020: Reverting r4685, r4686, r4687 (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/builtins-x64.cc ('k') | src/x64/full-codegen-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 1840 matching lines...) Expand 10 before | Expand all | Expand 10 after
1851 // the object) 1851 // the object)
1852 __ movq(rcx, rax); 1852 __ movq(rcx, rax);
1853 __ movq(rcx, FieldOperand(rcx, Map::kInstanceDescriptorsOffset)); 1853 __ movq(rcx, FieldOperand(rcx, Map::kInstanceDescriptorsOffset));
1854 // Get the bridge array held in the enumeration index field. 1854 // Get the bridge array held in the enumeration index field.
1855 __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset)); 1855 __ movq(rcx, FieldOperand(rcx, DescriptorArray::kEnumerationIndexOffset));
1856 // Get the cache from the bridge array. 1856 // Get the cache from the bridge array.
1857 __ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset)); 1857 __ movq(rdx, FieldOperand(rcx, DescriptorArray::kEnumCacheBridgeCacheOffset));
1858 1858
1859 frame_->EmitPush(rax); // <- slot 3 1859 frame_->EmitPush(rax); // <- slot 3
1860 frame_->EmitPush(rdx); // <- slot 2 1860 frame_->EmitPush(rdx); // <- slot 2
1861 __ movq(rax, FieldOperand(rdx, FixedArray::kLengthOffset)); 1861 __ movl(rax, FieldOperand(rdx, FixedArray::kLengthOffset));
1862 __ Integer32ToSmi(rax, rax);
1862 frame_->EmitPush(rax); // <- slot 1 1863 frame_->EmitPush(rax); // <- slot 1
1863 frame_->EmitPush(Smi::FromInt(0)); // <- slot 0 1864 frame_->EmitPush(Smi::FromInt(0)); // <- slot 0
1864 entry.Jump(); 1865 entry.Jump();
1865 1866
1866 fixed_array.Bind(); 1867 fixed_array.Bind();
1867 // rax: fixed array (result from call to Runtime::kGetPropertyNamesFast) 1868 // rax: fixed array (result from call to Runtime::kGetPropertyNamesFast)
1868 frame_->EmitPush(Smi::FromInt(0)); // <- slot 3 1869 frame_->EmitPush(Smi::FromInt(0)); // <- slot 3
1869 frame_->EmitPush(rax); // <- slot 2 1870 frame_->EmitPush(rax); // <- slot 2
1870 1871
1871 // Push the length of the array and the initial index onto the stack. 1872 // Push the length of the array and the initial index onto the stack.
1872 __ movq(rax, FieldOperand(rax, FixedArray::kLengthOffset)); 1873 __ movl(rax, FieldOperand(rax, FixedArray::kLengthOffset));
1874 __ Integer32ToSmi(rax, rax);
1873 frame_->EmitPush(rax); // <- slot 1 1875 frame_->EmitPush(rax); // <- slot 1
1874 frame_->EmitPush(Smi::FromInt(0)); // <- slot 0 1876 frame_->EmitPush(Smi::FromInt(0)); // <- slot 0
1875 1877
1876 // Condition. 1878 // Condition.
1877 entry.Bind(); 1879 entry.Bind();
1878 // Grab the current frame's height for the break and continue 1880 // Grab the current frame's height for the break and continue
1879 // targets only after all the state is pushed on the frame. 1881 // targets only after all the state is pushed on the frame.
1880 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY); 1882 node->break_target()->set_direction(JumpTarget::FORWARD_ONLY);
1881 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY); 1883 node->continue_target()->set_direction(JumpTarget::FORWARD_ONLY);
1882 1884
(...skipping 1950 matching lines...) Expand 10 before | Expand all | Expand 10 after
3833 3835
3834 __ Move(kScratchRegister, Factory::null_value()); 3836 __ Move(kScratchRegister, Factory::null_value());
3835 __ cmpq(obj.reg(), kScratchRegister); 3837 __ cmpq(obj.reg(), kScratchRegister);
3836 destination()->true_target()->Branch(equal); 3838 destination()->true_target()->Branch(equal);
3837 3839
3838 __ movq(kScratchRegister, FieldOperand(obj.reg(), HeapObject::kMapOffset)); 3840 __ movq(kScratchRegister, FieldOperand(obj.reg(), HeapObject::kMapOffset));
3839 // Undetectable objects behave like undefined when tested with typeof. 3841 // Undetectable objects behave like undefined when tested with typeof.
3840 __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset), 3842 __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
3841 Immediate(1 << Map::kIsUndetectable)); 3843 Immediate(1 << Map::kIsUndetectable));
3842 destination()->false_target()->Branch(not_zero); 3844 destination()->false_target()->Branch(not_zero);
3843 __ movzxbq(kScratchRegister, 3845 __ CmpInstanceType(kScratchRegister, FIRST_JS_OBJECT_TYPE);
3844 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset)); 3846 destination()->false_target()->Branch(less);
3845 __ cmpq(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE)); 3847 __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
3846 destination()->false_target()->Branch(below);
3847 __ cmpq(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE));
3848 obj.Unuse(); 3848 obj.Unuse();
3849 destination()->Split(below_equal); 3849 destination()->Split(less_equal);
3850 } 3850 }
3851 3851
3852 3852
3853 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) { 3853 void CodeGenerator::GenerateIsFunction(ZoneList<Expression*>* args) {
3854 // This generates a fast version of: 3854 // This generates a fast version of:
3855 // (%_ClassOf(arg) === 'Function') 3855 // (%_ClassOf(arg) === 'Function')
3856 ASSERT(args->length() == 1); 3856 ASSERT(args->length() == 1);
3857 Load(args->at(0)); 3857 Load(args->at(0));
3858 Result obj = frame_->Pop(); 3858 Result obj = frame_->Pop();
3859 obj.ToRegister(); 3859 obj.ToRegister();
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
4331 __ CallRuntime(Runtime::kNumberUnaryMinus, 1); 4331 __ CallRuntime(Runtime::kNumberUnaryMinus, 1);
4332 __ movq(rbx, rax); 4332 __ movq(rbx, rax);
4333 4333
4334 __ bind(&heapnumber_allocated); 4334 __ bind(&heapnumber_allocated);
4335 4335
4336 // Return a random uint32 number in rax. 4336 // Return a random uint32 number in rax.
4337 // The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs. 4337 // The fresh HeapNumber is in rbx, which is callee-save on both x64 ABIs.
4338 __ PrepareCallCFunction(0); 4338 __ PrepareCallCFunction(0);
4339 __ CallCFunction(ExternalReference::random_uint32_function(), 0); 4339 __ CallCFunction(ExternalReference::random_uint32_function(), 0);
4340 4340
4341 // Convert 32 random bits in rax to 0.(32 random bits) in a double 4341 // Convert 32 random bits in eax to 0.(32 random bits) in a double
4342 // by computing: 4342 // by computing:
4343 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 4343 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
4344 __ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 4344 __ movl(rcx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
4345 __ movd(xmm1, rcx); 4345 __ movd(xmm1, rcx);
4346 __ movd(xmm0, rax); 4346 __ movd(xmm0, rax);
4347 __ cvtss2sd(xmm1, xmm1); 4347 __ cvtss2sd(xmm1, xmm1);
4348 __ xorpd(xmm0, xmm1); 4348 __ xorpd(xmm0, xmm1);
4349 __ subsd(xmm0, xmm1); 4349 __ subsd(xmm0, xmm1);
4350 __ movsd(FieldOperand(rbx, HeapNumber::kValueOffset), xmm0); 4350 __ movsd(FieldOperand(rbx, HeapNumber::kValueOffset), xmm0);
4351 4351
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4426 4426
4427 // Fill out the elements FixedArray. 4427 // Fill out the elements FixedArray.
4428 // rax: JSArray. 4428 // rax: JSArray.
4429 // rcx: FixedArray. 4429 // rcx: FixedArray.
4430 // rbx: Number of elements in array as int32. 4430 // rbx: Number of elements in array as int32.
4431 4431
4432 // Set map. 4432 // Set map.
4433 __ Move(FieldOperand(rcx, HeapObject::kMapOffset), 4433 __ Move(FieldOperand(rcx, HeapObject::kMapOffset),
4434 Factory::fixed_array_map()); 4434 Factory::fixed_array_map());
4435 // Set length. 4435 // Set length.
4436 __ Integer32ToSmi(rdx, rbx); 4436 __ movl(FieldOperand(rcx, FixedArray::kLengthOffset), rbx);
4437 __ movq(FieldOperand(rcx, FixedArray::kLengthOffset), rdx);
4438 // Fill contents of fixed-array with the-hole. 4437 // Fill contents of fixed-array with the-hole.
4439 __ Move(rdx, Factory::the_hole_value()); 4438 __ Move(rdx, Factory::the_hole_value());
4440 __ lea(rcx, FieldOperand(rcx, FixedArray::kHeaderSize)); 4439 __ lea(rcx, FieldOperand(rcx, FixedArray::kHeaderSize));
4441 // Fill fixed array elements with hole. 4440 // Fill fixed array elements with hole.
4442 // rax: JSArray. 4441 // rax: JSArray.
4443 // rbx: Number of elements in array that remains to be filled, as int32. 4442 // rbx: Number of elements in array that remains to be filled, as int32.
4444 // rcx: Start of elements in FixedArray. 4443 // rcx: Start of elements in FixedArray.
4445 // rdx: the hole. 4444 // rdx: the hole.
4446 Label loop; 4445 Label loop;
4447 __ testl(rbx, rbx); 4446 __ testl(rbx, rbx);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
4546 __ InvokeFunction(rdi, expected, CALL_FUNCTION); 4545 __ InvokeFunction(rdi, expected, CALL_FUNCTION);
4547 4546
4548 // Find a place to put new cached value into. 4547 // Find a place to put new cached value into.
4549 Label add_new_entry, update_cache; 4548 Label add_new_entry, update_cache;
4550 __ movq(rcx, Operand(rsp, kPointerSize)); // restore the cache 4549 __ movq(rcx, Operand(rsp, kPointerSize)); // restore the cache
4551 // Possible optimization: cache size is constant for the given cache 4550 // Possible optimization: cache size is constant for the given cache
4552 // so technically we could use a constant here. However, if we have 4551 // so technically we could use a constant here. However, if we have
4553 // cache miss this optimization would hardly matter much. 4552 // cache miss this optimization would hardly matter much.
4554 4553
4555 // Check if we could add new entry to cache. 4554 // Check if we could add new entry to cache.
4556 __ movq(rbx, FieldOperand(rcx, FixedArray::kLengthOffset)); 4555 __ movl(rbx, FieldOperand(rcx, FixedArray::kLengthOffset));
4557 __ movq(r9, FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset)); 4556 __ movq(r9, FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset));
4558 __ SmiCompare(rbx, r9); 4557 __ SmiToInteger32(r9, r9);
4558 __ cmpq(rbx, r9);
4559 __ j(greater, &add_new_entry); 4559 __ j(greater, &add_new_entry);
4560 4560
4561 // Check if we could evict entry after finger. 4561 // Check if we could evict entry after finger.
4562 __ movq(rdx, FieldOperand(rcx, JSFunctionResultCache::kFingerOffset)); 4562 __ movq(rdx, FieldOperand(rcx, JSFunctionResultCache::kFingerOffset));
4563 __ SmiToInteger32(rdx, rdx); 4563 __ SmiToInteger32(rdx, rdx);
4564 __ SmiToInteger32(rbx, rbx);
4565 __ addq(rdx, kEntrySizeImm); 4564 __ addq(rdx, kEntrySizeImm);
4566 Label forward; 4565 Label forward;
4567 __ cmpq(rbx, rdx); 4566 __ cmpq(rbx, rdx);
4568 __ j(greater, &forward); 4567 __ j(greater, &forward);
4569 // Need to wrap over the cache. 4568 // Need to wrap over the cache.
4570 __ movq(rdx, kEntriesIndexImm); 4569 __ movq(rdx, kEntriesIndexImm);
4571 __ bind(&forward); 4570 __ bind(&forward);
4572 __ Integer32ToSmi(r9, rdx); 4571 __ Integer32ToSmi(r9, rdx);
4573 __ jmp(&update_cache); 4572 __ jmp(&update_cache);
4574 4573
4575 __ bind(&add_new_entry); 4574 __ bind(&add_new_entry);
4576 // r9 holds cache size as smi. 4575 // r9 holds cache size as int.
4577 __ SmiToInteger32(rdx, r9); 4576 __ movq(rdx, r9);
4577 __ Integer32ToSmi(r9, r9);
4578 __ SmiAddConstant(rbx, r9, Smi::FromInt(JSFunctionResultCache::kEntrySize)); 4578 __ SmiAddConstant(rbx, r9, Smi::FromInt(JSFunctionResultCache::kEntrySize));
4579 __ movq(FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx); 4579 __ movq(FieldOperand(rcx, JSFunctionResultCache::kCacheSizeOffset), rbx);
4580 4580
4581 // Update the cache itself. 4581 // Update the cache itself.
4582 // rdx holds the index as int. 4582 // rdx holds the index as int.
4583 // r9 holds the index as smi. 4583 // r9 holds the index as smi.
4584 __ bind(&update_cache); 4584 __ bind(&update_cache);
4585 __ pop(rbx); // restore the key 4585 __ pop(rbx); // restore the key
4586 __ movq(FieldOperand(rcx, JSFunctionResultCache::kFingerOffset), r9); 4586 __ movq(FieldOperand(rcx, JSFunctionResultCache::kFingerOffset), r9);
4587 // Store key. 4587 // Store key.
(...skipping 2537 matching lines...) Expand 10 before | Expand all | Expand 10 after
7125 Result key = frame_->Pop(); 7125 Result key = frame_->Pop();
7126 Result receiver = frame_->Pop(); 7126 Result receiver = frame_->Pop();
7127 key.ToRegister(); 7127 key.ToRegister();
7128 receiver.ToRegister(); 7128 receiver.ToRegister();
7129 7129
7130 // Use a fresh temporary to load the elements without destroying 7130 // Use a fresh temporary to load the elements without destroying
7131 // the receiver which is needed for the deferred slow case. 7131 // the receiver which is needed for the deferred slow case.
7132 Result elements = allocator()->Allocate(); 7132 Result elements = allocator()->Allocate();
7133 ASSERT(elements.is_valid()); 7133 ASSERT(elements.is_valid());
7134 7134
7135 // Use a fresh temporary for the index and later the loaded
7136 // value.
7137 Result index = allocator()->Allocate();
7138 ASSERT(index.is_valid());
7139
7135 DeferredReferenceGetKeyedValue* deferred = 7140 DeferredReferenceGetKeyedValue* deferred =
7136 new DeferredReferenceGetKeyedValue(elements.reg(), 7141 new DeferredReferenceGetKeyedValue(index.reg(),
7137 receiver.reg(), 7142 receiver.reg(),
7138 key.reg(), 7143 key.reg(),
7139 is_global); 7144 is_global);
7140 7145
7141 // Check that the receiver is not a smi (only needed if this 7146 // Check that the receiver is not a smi (only needed if this
7142 // is not a load from the global context) and that it has the 7147 // is not a load from the global context) and that it has the
7143 // expected map. 7148 // expected map.
7144 if (!is_global) { 7149 if (!is_global) {
7145 __ JumpIfSmi(receiver.reg(), deferred->entry_label()); 7150 __ JumpIfSmi(receiver.reg(), deferred->entry_label());
7146 } 7151 }
(...skipping 15 matching lines...) Expand all
7162 __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label()); 7167 __ JumpIfNotPositiveSmi(key.reg(), deferred->entry_label());
7163 7168
7164 // Get the elements array from the receiver and check that it 7169 // Get the elements array from the receiver and check that it
7165 // is not a dictionary. 7170 // is not a dictionary.
7166 __ movq(elements.reg(), 7171 __ movq(elements.reg(),
7167 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); 7172 FieldOperand(receiver.reg(), JSObject::kElementsOffset));
7168 __ Cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), 7173 __ Cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset),
7169 Factory::fixed_array_map()); 7174 Factory::fixed_array_map());
7170 deferred->Branch(not_equal); 7175 deferred->Branch(not_equal);
7171 7176
7172 // Check that key is within bounds. 7177 // Shift the key to get the actual index value and check that
7173 __ SmiCompare(key.reg(), 7178 // it is within bounds.
7174 FieldOperand(elements.reg(), FixedArray::kLengthOffset)); 7179 __ SmiToInteger32(index.reg(), key.reg());
7180 __ cmpl(index.reg(),
7181 FieldOperand(elements.reg(), FixedArray::kLengthOffset));
7175 deferred->Branch(above_equal); 7182 deferred->Branch(above_equal);
7176 7183
7177 // The key register holds the smi-tagged key. Load the value and 7184 // The index register holds the un-smi-tagged key. It has been
7178 // check that it is not the hole value. 7185 // zero-extended to 64-bits, so it can be used directly as index in the
7179 Result value = elements; 7186 // operand below.
7180 SmiIndex index = 7187 // Load and check that the result is not the hole. We could
7181 masm_->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); 7188 // reuse the index or elements register for the value.
7189 //
7190 // TODO(206): Consider whether it makes sense to try some
7191 // heuristic about which register to reuse. For example, if
7192 // one is rax, the we can reuse that one because the value
7193 // coming from the deferred code will be in rax.
7194 Result value = index;
7182 __ movq(value.reg(), 7195 __ movq(value.reg(),
7183 FieldOperand(elements.reg(), 7196 Operand(elements.reg(),
7184 index.reg, 7197 index.reg(),
7185 index.scale, 7198 times_pointer_size,
7186 FixedArray::kHeaderSize)); 7199 FixedArray::kHeaderSize - kHeapObjectTag));
7200 elements.Unuse();
7201 index.Unuse();
7187 __ CompareRoot(value.reg(), Heap::kTheHoleValueRootIndex); 7202 __ CompareRoot(value.reg(), Heap::kTheHoleValueRootIndex);
7188 deferred->Branch(equal); 7203 deferred->Branch(equal);
7189 __ IncrementCounter(&Counters::keyed_load_inline, 1); 7204 __ IncrementCounter(&Counters::keyed_load_inline, 1);
7190 7205
7191 deferred->BindExit(); 7206 deferred->BindExit();
7192 // Restore the receiver and key to the frame and push the 7207 // Restore the receiver and key to the frame and push the
7193 // result on top of it. 7208 // result on top of it.
7194 frame_->Push(&receiver); 7209 frame_->Push(&receiver);
7195 frame_->Push(&key); 7210 frame_->Push(&key);
7196 return value; 7211 return value;
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
7475 key.reg()); 7490 key.reg());
7476 deferred->Branch(below_equal); 7491 deferred->Branch(below_equal);
7477 7492
7478 // Get the elements array from the receiver and check that it 7493 // Get the elements array from the receiver and check that it
7479 // is a flat array (not a dictionary). 7494 // is a flat array (not a dictionary).
7480 __ movq(tmp.reg(), 7495 __ movq(tmp.reg(),
7481 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); 7496 FieldOperand(receiver.reg(), JSObject::kElementsOffset));
7482 7497
7483 // Check whether it is possible to omit the write barrier. If the 7498 // Check whether it is possible to omit the write barrier. If the
7484 // elements array is in new space or the value written is a smi we can 7499 // elements array is in new space or the value written is a smi we can
7485 // safely update the elements array without write barrier. 7500 // safely update the elements array without updating the remembered set.
7486 Label in_new_space; 7501 Label in_new_space;
7487 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space); 7502 __ InNewSpace(tmp.reg(), tmp2.reg(), equal, &in_new_space);
7488 if (!value_is_constant) { 7503 if (!value_is_constant) {
7489 __ JumpIfNotSmi(value.reg(), deferred->entry_label()); 7504 __ JumpIfNotSmi(value.reg(), deferred->entry_label());
7490 } 7505 }
7491 7506
7492 __ bind(&in_new_space); 7507 __ bind(&in_new_space);
7493 // Bind the deferred code patch site to be able to locate the 7508 // Bind the deferred code patch site to be able to locate the
7494 // fixed array map comparison. When debugging, we patch this 7509 // fixed array map comparison. When debugging, we patch this
7495 // comparison to always fail so that we will hit the IC call 7510 // comparison to always fail so that we will hit the IC call
7496 // in the deferred code which will allow the debugger to 7511 // in the deferred code which will allow the debugger to
7497 // break for fast case stores. 7512 // break for fast case stores.
7498 __ bind(deferred->patch_site()); 7513 __ bind(deferred->patch_site());
7499 // Avoid using __ to ensure the distance from patch_site 7514 // Avoid using __ to ensure the distance from patch_site
7500 // to the map address is always the same. 7515 // to the map address is always the same.
7501 masm->movq(kScratchRegister, Factory::fixed_array_map(), 7516 masm->movq(kScratchRegister, Factory::fixed_array_map(),
7502 RelocInfo::EMBEDDED_OBJECT); 7517 RelocInfo::EMBEDDED_OBJECT);
7503 __ cmpq(FieldOperand(tmp.reg(), HeapObject::kMapOffset), 7518 __ cmpq(FieldOperand(tmp.reg(), HeapObject::kMapOffset),
7504 kScratchRegister); 7519 kScratchRegister);
7505 deferred->Branch(not_equal); 7520 deferred->Branch(not_equal);
7506 7521
7507 // Store the value. 7522 // Store the value.
7508 SmiIndex index = 7523 SmiIndex index =
7509 masm->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); 7524 masm->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2);
7510 __ movq(FieldOperand(tmp.reg(), 7525 __ movq(Operand(tmp.reg(),
7511 index.reg, 7526 index.reg,
7512 index.scale, 7527 index.scale,
7513 FixedArray::kHeaderSize), 7528 FixedArray::kHeaderSize - kHeapObjectTag),
7514 value.reg()); 7529 value.reg());
7515 __ IncrementCounter(&Counters::keyed_store_inline, 1); 7530 __ IncrementCounter(&Counters::keyed_store_inline, 1);
7516 7531
7517 deferred->BindExit(); 7532 deferred->BindExit();
7518 7533
7519 cgen_->frame()->Push(&receiver); 7534 cgen_->frame()->Push(&receiver);
7520 cgen_->frame()->Push(&key); 7535 cgen_->frame()->Push(&key);
7521 cgen_->frame()->Push(&value); 7536 cgen_->frame()->Push(&value);
7522 } else { 7537 } else {
7523 Result answer = cgen_->frame()->CallKeyedStoreIC(); 7538 Result answer = cgen_->frame()->CallKeyedStoreIC();
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
7585 int length = slots_ + Context::MIN_CONTEXT_SLOTS; 7600 int length = slots_ + Context::MIN_CONTEXT_SLOTS;
7586 __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize, 7601 __ AllocateInNewSpace((length * kPointerSize) + FixedArray::kHeaderSize,
7587 rax, rbx, rcx, &gc, TAG_OBJECT); 7602 rax, rbx, rcx, &gc, TAG_OBJECT);
7588 7603
7589 // Get the function from the stack. 7604 // Get the function from the stack.
7590 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 7605 __ movq(rcx, Operand(rsp, 1 * kPointerSize));
7591 7606
7592 // Setup the object header. 7607 // Setup the object header.
7593 __ LoadRoot(kScratchRegister, Heap::kContextMapRootIndex); 7608 __ LoadRoot(kScratchRegister, Heap::kContextMapRootIndex);
7594 __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister); 7609 __ movq(FieldOperand(rax, HeapObject::kMapOffset), kScratchRegister);
7595 __ Move(FieldOperand(rax, FixedArray::kLengthOffset), Smi::FromInt(length)); 7610 __ movl(FieldOperand(rax, Array::kLengthOffset), Immediate(length));
7596 7611
7597 // Setup the fixed slots. 7612 // Setup the fixed slots.
7598 __ xor_(rbx, rbx); // Set to NULL. 7613 __ xor_(rbx, rbx); // Set to NULL.
7599 __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx); 7614 __ movq(Operand(rax, Context::SlotOffset(Context::CLOSURE_INDEX)), rcx);
7600 __ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax); 7615 __ movq(Operand(rax, Context::SlotOffset(Context::FCONTEXT_INDEX)), rax);
7601 __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx); 7616 __ movq(Operand(rax, Context::SlotOffset(Context::PREVIOUS_INDEX)), rbx);
7602 __ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx); 7617 __ movq(Operand(rax, Context::SlotOffset(Context::EXTENSION_INDEX)), rbx);
7603 7618
7604 // Copy the global object from the surrounding context. 7619 // Copy the global object from the surrounding context.
7605 __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 7620 __ movq(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
8260 __ CmpObjectType(rax, JS_ARRAY_TYPE, kScratchRegister); 8275 __ CmpObjectType(rax, JS_ARRAY_TYPE, kScratchRegister);
8261 __ j(not_equal, &runtime); 8276 __ j(not_equal, &runtime);
8262 // Check that the JSArray is in fast case. 8277 // Check that the JSArray is in fast case.
8263 __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset)); 8278 __ movq(rbx, FieldOperand(rax, JSArray::kElementsOffset));
8264 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset)); 8279 __ movq(rax, FieldOperand(rbx, HeapObject::kMapOffset));
8265 __ Cmp(rax, Factory::fixed_array_map()); 8280 __ Cmp(rax, Factory::fixed_array_map());
8266 __ j(not_equal, &runtime); 8281 __ j(not_equal, &runtime);
8267 // Check that the last match info has space for the capture registers and the 8282 // Check that the last match info has space for the capture registers and the
8268 // additional information. Ensure no overflow in add. 8283 // additional information. Ensure no overflow in add.
8269 ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); 8284 ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
8270 __ movq(rax, FieldOperand(rbx, FixedArray::kLengthOffset)); 8285 __ movl(rax, FieldOperand(rbx, FixedArray::kLengthOffset));
8271 __ SmiToInteger32(rax, rax);
8272 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead)); 8286 __ addl(rdx, Immediate(RegExpImpl::kLastMatchOverhead));
8273 __ cmpl(rdx, rax); 8287 __ cmpl(rdx, rax);
8274 __ j(greater, &runtime); 8288 __ j(greater, &runtime);
8275 8289
8276 // ecx: RegExp data (FixedArray) 8290 // ecx: RegExp data (FixedArray)
8277 // Check the representation and encoding of the subject string. 8291 // Check the representation and encoding of the subject string.
8278 Label seq_string, seq_two_byte_string, check_code; 8292 Label seq_string, seq_two_byte_string, check_code;
8279 const int kStringRepresentationEncodingMask = 8293 const int kStringRepresentationEncodingMask =
8280 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask; 8294 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
8281 __ movq(rax, Operand(rsp, kSubjectOffset)); 8295 __ movq(rax, Operand(rsp, kSubjectOffset));
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
8539 // Use of registers. Register result is used as a temporary. 8553 // Use of registers. Register result is used as a temporary.
8540 Register number_string_cache = result; 8554 Register number_string_cache = result;
8541 Register mask = scratch1; 8555 Register mask = scratch1;
8542 Register scratch = scratch2; 8556 Register scratch = scratch2;
8543 8557
8544 // Load the number string cache. 8558 // Load the number string cache.
8545 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex); 8559 __ LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
8546 8560
8547 // Make the hash mask from the length of the number string cache. It 8561 // Make the hash mask from the length of the number string cache. It
8548 // contains two elements (number and string) for each cache entry. 8562 // contains two elements (number and string) for each cache entry.
8549 __ movq(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset)); 8563 __ movl(mask, FieldOperand(number_string_cache, FixedArray::kLengthOffset));
8550 // Divide smi tagged length by two. 8564 __ shrl(mask, Immediate(1)); // Divide length by two (length is not a smi).
8551 __ PositiveSmiDivPowerOfTwoToInteger32(mask, mask, 1); 8565 __ subl(mask, Immediate(1)); // Make mask.
8552 __ subq(mask, Immediate(1)); // Make mask.
8553 8566
8554 // Calculate the entry in the number string cache. The hash value in the 8567 // Calculate the entry in the number string cache. The hash value in the
8555 // number string cache for smis is just the smi value, and the hash for 8568 // number string cache for smis is just the smi value, and the hash for
8556 // doubles is the xor of the upper and lower words. See 8569 // doubles is the xor of the upper and lower words. See
8557 // Heap::GetNumberStringCache. 8570 // Heap::GetNumberStringCache.
8558 Label is_smi; 8571 Label is_smi;
8559 Label load_result_from_cache; 8572 Label load_result_from_cache;
8560 if (!object_is_smi) { 8573 if (!object_is_smi) {
8561 __ JumpIfSmi(object, &is_smi); 8574 __ JumpIfSmi(object, &is_smi);
8562 __ CheckMap(object, Factory::heap_number_map(), not_found, true); 8575 __ CheckMap(object, Factory::heap_number_map(), not_found, true);
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
9062 __ movq(rcx, Operand(rsp, 1 * kPointerSize)); 9075 __ movq(rcx, Operand(rsp, 1 * kPointerSize));
9063 __ movq(FieldOperand(rax, JSObject::kHeaderSize + kPointerSize), rcx); 9076 __ movq(FieldOperand(rax, JSObject::kHeaderSize + kPointerSize), rcx);
9064 9077
9065 // If there are no actual arguments, we're done. 9078 // If there are no actual arguments, we're done.
9066 Label done; 9079 Label done;
9067 __ testq(rcx, rcx); 9080 __ testq(rcx, rcx);
9068 __ j(zero, &done); 9081 __ j(zero, &done);
9069 9082
9070 // Get the parameters pointer from the stack and untag the length. 9083 // Get the parameters pointer from the stack and untag the length.
9071 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); 9084 __ movq(rdx, Operand(rsp, 2 * kPointerSize));
9085 __ SmiToInteger32(rcx, rcx);
9072 9086
9073 // Setup the elements pointer in the allocated arguments object and 9087 // Setup the elements pointer in the allocated arguments object and
9074 // initialize the header in the elements fixed array. 9088 // initialize the header in the elements fixed array.
9075 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize)); 9089 __ lea(rdi, Operand(rax, Heap::kArgumentsObjectSize));
9076 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi); 9090 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rdi);
9077 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex); 9091 __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
9078 __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister); 9092 __ movq(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
9079 __ movq(FieldOperand(rdi, FixedArray::kLengthOffset), rcx); 9093 __ movl(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
9080 __ SmiToInteger32(rcx, rcx); // Untag length for the loop below.
9081 9094
9082 // Copy the fixed array slots. 9095 // Copy the fixed array slots.
9083 Label loop; 9096 Label loop;
9084 __ bind(&loop); 9097 __ bind(&loop);
9085 __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize)); // Skip receiver. 9098 __ movq(kScratchRegister, Operand(rdx, -1 * kPointerSize)); // Skip receiver.
9086 __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister); 9099 __ movq(FieldOperand(rdi, FixedArray::kHeaderSize), kScratchRegister);
9087 __ addq(rdi, Immediate(kPointerSize)); 9100 __ addq(rdi, Immediate(kPointerSize));
9088 __ subq(rdx, Immediate(kPointerSize)); 9101 __ subq(rdx, Immediate(kPointerSize));
9089 __ decq(rcx); 9102 __ decq(rcx);
9090 __ j(not_zero, &loop); 9103 __ j(not_zero, &loop);
(...skipping 1750 matching lines...) Expand 10 before | Expand all | Expand 10 after
10841 __ movl(rcx, r8); 10854 __ movl(rcx, r8);
10842 __ and_(rcx, r9); 10855 __ and_(rcx, r9);
10843 ASSERT(kStringEncodingMask == kAsciiStringTag); 10856 ASSERT(kStringEncodingMask == kAsciiStringTag);
10844 __ testl(rcx, Immediate(kAsciiStringTag)); 10857 __ testl(rcx, Immediate(kAsciiStringTag));
10845 __ j(zero, &non_ascii); 10858 __ j(zero, &non_ascii);
10846 // Allocate an acsii cons string. 10859 // Allocate an acsii cons string.
10847 __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime); 10860 __ AllocateAsciiConsString(rcx, rdi, no_reg, &string_add_runtime);
10848 __ bind(&allocated); 10861 __ bind(&allocated);
10849 // Fill the fields of the cons string. 10862 // Fill the fields of the cons string.
10850 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx); 10863 __ movq(FieldOperand(rcx, ConsString::kLengthOffset), rbx);
10851 __ movq(FieldOperand(rcx, ConsString::kHashFieldOffset), 10864 __ movl(FieldOperand(rcx, ConsString::kHashFieldOffset),
10852 Immediate(String::kEmptyHashField)); 10865 Immediate(String::kEmptyHashField));
10853 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax); 10866 __ movq(FieldOperand(rcx, ConsString::kFirstOffset), rax);
10854 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx); 10867 __ movq(FieldOperand(rcx, ConsString::kSecondOffset), rdx);
10855 __ movq(rax, rcx); 10868 __ movq(rax, rcx);
10856 __ IncrementCounter(&Counters::string_add_native, 1); 10869 __ IncrementCounter(&Counters::string_add_native, 1);
10857 __ ret(2 * kPointerSize); 10870 __ ret(2 * kPointerSize);
10858 __ bind(&non_ascii); 10871 __ bind(&non_ascii);
10859 // Allocate a two byte cons string. 10872 // Allocate a two byte cons string.
10860 __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime); 10873 __ AllocateConsString(rcx, rdi, no_reg, &string_add_runtime);
10861 __ jmp(&allocated); 10874 __ jmp(&allocated);
(...skipping 717 matching lines...) Expand 10 before | Expand all | Expand 10 after
11579 } 11592 }
11580 11593
11581 #endif 11594 #endif
11582 11595
11583 11596
11584 #undef __ 11597 #undef __
11585 11598
11586 } } // namespace v8::internal 11599 } } // namespace v8::internal
11587 11600
11588 #endif // V8_TARGET_ARCH_X64 11601 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/builtins-x64.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698