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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 1 month 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/code-stubs-x64.h ('k') | src/x64/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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 220
221 221
222 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { 222 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) {
223 // Stack layout on entry: 223 // Stack layout on entry:
224 // 224 //
225 // [rsp + kPointerSize]: constant elements. 225 // [rsp + kPointerSize]: constant elements.
226 // [rsp + (2 * kPointerSize)]: literal index. 226 // [rsp + (2 * kPointerSize)]: literal index.
227 // [rsp + (3 * kPointerSize)]: literals array. 227 // [rsp + (3 * kPointerSize)]: literals array.
228 228
229 // All sizes here are multiples of kPointerSize. 229 // All sizes here are multiples of kPointerSize.
230 int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0; 230 int elements_size = 0;
231 if (length_ > 0) {
232 elements_size = mode_ == CLONE_DOUBLE_ELEMENTS
233 ? FixedDoubleArray::SizeFor(length_)
234 : FixedArray::SizeFor(length_);
235 }
231 int size = JSArray::kSize + elements_size; 236 int size = JSArray::kSize + elements_size;
232 237
233 // Load boilerplate object into rcx and check if we need to create a 238 // Load boilerplate object into rcx and check if we need to create a
234 // boilerplate. 239 // boilerplate.
235 Label slow_case; 240 Label slow_case;
236 __ movq(rcx, Operand(rsp, 3 * kPointerSize)); 241 __ movq(rcx, Operand(rsp, 3 * kPointerSize));
237 __ movq(rax, Operand(rsp, 2 * kPointerSize)); 242 __ movq(rax, Operand(rsp, 2 * kPointerSize));
238 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2); 243 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
239 __ movq(rcx, 244 __ movq(rcx,
240 FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize)); 245 FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize));
241 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); 246 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
242 __ j(equal, &slow_case); 247 __ j(equal, &slow_case);
243 248
244 if (FLAG_debug_code) { 249 if (FLAG_debug_code) {
245 const char* message; 250 const char* message;
246 Heap::RootListIndex expected_map_index; 251 Heap::RootListIndex expected_map_index;
247 if (mode_ == CLONE_ELEMENTS) { 252 if (mode_ == CLONE_ELEMENTS) {
248 message = "Expected (writable) fixed array"; 253 message = "Expected (writable) fixed array";
249 expected_map_index = Heap::kFixedArrayMapRootIndex; 254 expected_map_index = Heap::kFixedArrayMapRootIndex;
255 } else if (mode_ == CLONE_DOUBLE_ELEMENTS) {
256 message = "Expected (writable) fixed double array";
257 expected_map_index = Heap::kFixedDoubleArrayMapRootIndex;
250 } else { 258 } else {
251 ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS); 259 ASSERT(mode_ == COPY_ON_WRITE_ELEMENTS);
252 message = "Expected copy-on-write fixed array"; 260 message = "Expected copy-on-write fixed array";
253 expected_map_index = Heap::kFixedCOWArrayMapRootIndex; 261 expected_map_index = Heap::kFixedCOWArrayMapRootIndex;
254 } 262 }
255 __ push(rcx); 263 __ push(rcx);
256 __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset)); 264 __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
257 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 265 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
258 expected_map_index); 266 expected_map_index);
259 __ Assert(equal, message); 267 __ Assert(equal, message);
(...skipping 13 matching lines...) Expand all
273 } 281 }
274 282
275 if (length_ > 0) { 283 if (length_ > 0) {
276 // Get hold of the elements array of the boilerplate and setup the 284 // Get hold of the elements array of the boilerplate and setup the
277 // elements pointer in the resulting object. 285 // elements pointer in the resulting object.
278 __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset)); 286 __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset));
279 __ lea(rdx, Operand(rax, JSArray::kSize)); 287 __ lea(rdx, Operand(rax, JSArray::kSize));
280 __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx); 288 __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx);
281 289
282 // Copy the elements array. 290 // Copy the elements array.
283 for (int i = 0; i < elements_size; i += kPointerSize) { 291 if (mode_ == CLONE_ELEMENTS) {
284 __ movq(rbx, FieldOperand(rcx, i)); 292 for (int i = 0; i < elements_size; i += kPointerSize) {
285 __ movq(FieldOperand(rdx, i), rbx); 293 __ movq(rbx, FieldOperand(rcx, i));
294 __ movq(FieldOperand(rdx, i), rbx);
295 }
296 } else {
297 ASSERT(mode_ == CLONE_DOUBLE_ELEMENTS);
298 int i;
299 for (i = 0; i < FixedDoubleArray::kHeaderSize; i += kPointerSize) {
300 __ movq(rbx, FieldOperand(rcx, i));
301 __ movq(FieldOperand(rdx, i), rbx);
302 }
303 while (i < elements_size) {
304 __ movsd(xmm0, FieldOperand(rcx, i));
305 __ movsd(FieldOperand(rdx, i), xmm0);
306 i += kDoubleSize;
307 }
308 ASSERT(i == elements_size);
286 } 309 }
287 } 310 }
288 311
289 // Return and remove the on-stack parameters. 312 // Return and remove the on-stack parameters.
290 __ ret(3 * kPointerSize); 313 __ ret(3 * kPointerSize);
291 314
292 __ bind(&slow_case); 315 __ bind(&slow_case);
293 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1); 316 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1);
294 } 317 }
295 318
(...skipping 3576 matching lines...) Expand 10 before | Expand all | Expand 10 after
3872 Label miss; 3895 Label miss;
3873 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); 3896 __ CompareRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex);
3874 __ j(not_equal, &miss, Label::kNear); 3897 __ j(not_equal, &miss, Label::kNear);
3875 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex); 3898 __ CompareRoot(rax, Heap::kInstanceofCacheMapRootIndex);
3876 __ j(not_equal, &miss, Label::kNear); 3899 __ j(not_equal, &miss, Label::kNear);
3877 __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex); 3900 __ LoadRoot(rax, Heap::kInstanceofCacheAnswerRootIndex);
3878 __ ret(2 * kPointerSize); 3901 __ ret(2 * kPointerSize);
3879 __ bind(&miss); 3902 __ bind(&miss);
3880 } 3903 }
3881 3904
3882 __ TryGetFunctionPrototype(rdx, rbx, &slow); 3905 __ TryGetFunctionPrototype(rdx, rbx, &slow, true);
3883 3906
3884 // Check that the function prototype is a JS object. 3907 // Check that the function prototype is a JS object.
3885 __ JumpIfSmi(rbx, &slow); 3908 __ JumpIfSmi(rbx, &slow);
3886 __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, kScratchRegister); 3909 __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
3887 __ j(below, &slow); 3910 __ j(below, &slow);
3888 __ CmpInstanceType(kScratchRegister, LAST_SPEC_OBJECT_TYPE); 3911 __ CmpInstanceType(kScratchRegister, LAST_SPEC_OBJECT_TYPE);
3889 __ j(above, &slow); 3912 __ j(above, &slow);
3890 3913
3891 // Register mapping: 3914 // Register mapping:
3892 // rax is object map. 3915 // rax is object map.
(...skipping 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after
5431 __ pop(rcx); 5454 __ pop(rcx);
5432 __ pop(rax); 5455 __ pop(rax);
5433 __ pop(rdx); 5456 __ pop(rdx);
5434 __ push(rcx); 5457 __ push(rcx);
5435 5458
5436 // Do a tail call to the rewritten stub. 5459 // Do a tail call to the rewritten stub.
5437 __ jmp(rdi); 5460 __ jmp(rdi);
5438 } 5461 }
5439 5462
5440 5463
5441 MaybeObject* StringDictionaryLookupStub::GenerateNegativeLookup( 5464 void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm,
5465 Label* miss,
5466 Label* done,
5467 Register properties,
5468 Handle<String> name,
5469 Register r0) {
5470 // If names of slots in range from 1 to kProbes - 1 for the hash value are
5471 // not equal to the name and kProbes-th slot is not used (its name is the
5472 // undefined value), it guarantees the hash table doesn't contain the
5473 // property. It's true even if some slots represent deleted properties
5474 // (their names are the null value).
5475 for (int i = 0; i < kInlinedProbes; i++) {
5476 // r0 points to properties hash.
5477 // Compute the masked index: (hash + i + i * i) & mask.
5478 Register index = r0;
5479 // Capacity is smi 2^n.
5480 __ SmiToInteger32(index, FieldOperand(properties, kCapacityOffset));
5481 __ decl(index);
5482 __ and_(index,
5483 Immediate(name->Hash() + StringDictionary::GetProbeOffset(i)));
5484
5485 // Scale the index by multiplying by the entry size.
5486 ASSERT(StringDictionary::kEntrySize == 3);
5487 __ lea(index, Operand(index, index, times_2, 0)); // index *= 3.
5488
5489 Register entity_name = r0;
5490 // Having undefined at this place means the name is not contained.
5491 ASSERT_EQ(kSmiTagSize, 1);
5492 __ movq(entity_name, Operand(properties,
5493 index,
5494 times_pointer_size,
5495 kElementsStartOffset - kHeapObjectTag));
5496 __ Cmp(entity_name, masm->isolate()->factory()->undefined_value());
5497 __ j(equal, done);
5498
5499 // Stop if found the property.
5500 __ Cmp(entity_name, Handle<String>(name));
5501 __ j(equal, miss);
5502
5503 // Check if the entry name is not a symbol.
5504 __ movq(entity_name, FieldOperand(entity_name, HeapObject::kMapOffset));
5505 __ testb(FieldOperand(entity_name, Map::kInstanceTypeOffset),
5506 Immediate(kIsSymbolMask));
5507 __ j(zero, miss);
5508 }
5509
5510 StringDictionaryLookupStub stub(properties,
5511 r0,
5512 r0,
5513 StringDictionaryLookupStub::NEGATIVE_LOOKUP);
5514 __ Push(Handle<Object>(name));
5515 __ push(Immediate(name->Hash()));
5516 __ CallStub(&stub);
5517 __ testq(r0, r0);
5518 __ j(not_zero, miss);
5519 __ jmp(done);
5520 }
5521
5522
5523 // TODO(kmillikin): Eliminate this function when the stub cache is fully
5524 // handlified.
5525 MaybeObject* StringDictionaryLookupStub::TryGenerateNegativeLookup(
5442 MacroAssembler* masm, 5526 MacroAssembler* masm,
5443 Label* miss, 5527 Label* miss,
5444 Label* done, 5528 Label* done,
5445 Register properties, 5529 Register properties,
5446 String* name, 5530 String* name,
5447 Register r0) { 5531 Register r0) {
5448 // If names of slots in range from 1 to kProbes - 1 for the hash value are 5532 // If names of slots in range from 1 to kProbes - 1 for the hash value are
5449 // not equal to the name and kProbes-th slot is not used (its name is the 5533 // not equal to the name and kProbes-th slot is not used (its name is the
5450 // undefined value), it guarantees the hash table doesn't contain the 5534 // undefined value), it guarantees the hash table doesn't contain the
5451 // property. It's true even if some slots represent deleted properties 5535 // property. It's true even if some slots represent deleted properties
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
5658 { rdx, rcx, rbx, EMIT_REMEMBERED_SET }, 5742 { rdx, rcx, rbx, EMIT_REMEMBERED_SET },
5659 // GenerateStoreField calls the stub with two different permutations of 5743 // GenerateStoreField calls the stub with two different permutations of
5660 // registers. This is the second. 5744 // registers. This is the second.
5661 { rbx, rcx, rdx, EMIT_REMEMBERED_SET }, 5745 { rbx, rcx, rdx, EMIT_REMEMBERED_SET },
5662 // StoreIC::GenerateNormal via GenerateDictionaryStore. 5746 // StoreIC::GenerateNormal via GenerateDictionaryStore.
5663 { rbx, r8, r9, EMIT_REMEMBERED_SET }, 5747 { rbx, r8, r9, EMIT_REMEMBERED_SET },
5664 // KeyedStoreIC::GenerateGeneric. 5748 // KeyedStoreIC::GenerateGeneric.
5665 { rbx, rdx, rcx, EMIT_REMEMBERED_SET}, 5749 { rbx, rdx, rcx, EMIT_REMEMBERED_SET},
5666 // KeyedStoreStubCompiler::GenerateStoreFastElement. 5750 // KeyedStoreStubCompiler::GenerateStoreFastElement.
5667 { rdi, rdx, rcx, EMIT_REMEMBERED_SET}, 5751 { rdi, rdx, rcx, EMIT_REMEMBERED_SET},
5752 // ElementsTransitionGenerator::GenerateSmiOnlyToObject
5753 // and ElementsTransitionGenerator::GenerateSmiOnlyToObject
5754 // and ElementsTransitionGenerator::GenerateDoubleToObject
5755 { rdx, rbx, rdi, EMIT_REMEMBERED_SET},
5756 // ElementsTransitionGenerator::GenerateSmiOnlyToDouble
5757 // and ElementsTransitionGenerator::GenerateDoubleToObject
5758 { rdx, r11, r15, EMIT_REMEMBERED_SET},
5759 // ElementsTransitionGenerator::GenerateDoubleToObject
5760 { r11, rax, r15, EMIT_REMEMBERED_SET},
5668 // Null termination. 5761 // Null termination.
5669 { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET} 5762 { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET}
5670 }; 5763 };
5671 5764
5672 5765
5673 bool RecordWriteStub::IsPregenerated() { 5766 bool RecordWriteStub::IsPregenerated() {
5674 for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; 5767 for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime;
5675 !entry->object.is(no_reg); 5768 !entry->object.is(no_reg);
5676 entry++) { 5769 entry++) {
5677 if (object_.is(entry->object) && 5770 if (object_.is(entry->object) &&
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
5905 } 5998 }
5906 5999
5907 __ bind(&need_incremental_pop_object); 6000 __ bind(&need_incremental_pop_object);
5908 __ pop(regs_.object()); 6001 __ pop(regs_.object());
5909 6002
5910 __ bind(&need_incremental); 6003 __ bind(&need_incremental);
5911 6004
5912 // Fall through when we need to inform the incremental marker. 6005 // Fall through when we need to inform the incremental marker.
5913 } 6006 }
5914 6007
5915
5916 #undef __ 6008 #undef __
5917 6009
5918 } } // namespace v8::internal 6010 } } // namespace v8::internal
5919 6011
5920 #endif // V8_TARGET_ARCH_X64 6012 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698