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

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

Issue 6677076: Merge up to bleeding_edge r7201 to isolates branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/isolates
Patch Set: Fix lint. Created 9 years, 9 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/assembler-x64.cc ('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 2229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2240 2240
2241 // The displacement is used for skipping the frame pointer on the 2241 // The displacement is used for skipping the frame pointer on the
2242 // stack. It is the offset of the last parameter (if any) relative 2242 // stack. It is the offset of the last parameter (if any) relative
2243 // to the frame pointer. 2243 // to the frame pointer.
2244 static const int kDisplacement = 1 * kPointerSize; 2244 static const int kDisplacement = 1 * kPointerSize;
2245 2245
2246 // Check that the key is a smi. 2246 // Check that the key is a smi.
2247 Label slow; 2247 Label slow;
2248 __ JumpIfNotSmi(rdx, &slow); 2248 __ JumpIfNotSmi(rdx, &slow);
2249 2249
2250 // Check if the calling frame is an arguments adaptor frame. 2250 // Check if the calling frame is an arguments adaptor frame. We look at the
2251 // context offset, and if the frame is not a regular one, then we find a
2252 // Smi instead of the context. We can't use SmiCompare here, because that
2253 // only works for comparing two smis.
2251 Label adaptor; 2254 Label adaptor;
2252 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2255 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2253 __ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset), 2256 __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset),
2254 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2257 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2255 __ j(equal, &adaptor); 2258 __ j(equal, &adaptor);
2256 2259
2257 // Check index against formal parameters count limit passed in 2260 // Check index against formal parameters count limit passed in
2258 // through register rax. Use unsigned comparison to get negative 2261 // through register rax. Use unsigned comparison to get negative
2259 // check for free. 2262 // check for free.
2260 __ cmpq(rdx, rax); 2263 __ cmpq(rdx, rax);
2261 __ j(above_equal, &slow); 2264 __ j(above_equal, &slow);
2262 2265
2263 // Read the argument from the stack and return it. 2266 // Read the argument from the stack and return it.
2264 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2); 2267 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 // rsp[24] : function 2302 // rsp[24] : function
2300 2303
2301 // The displacement is used for skipping the return address and the 2304 // The displacement is used for skipping the return address and the
2302 // frame pointer on the stack. It is the offset of the last 2305 // frame pointer on the stack. It is the offset of the last
2303 // parameter (if any) relative to the frame pointer. 2306 // parameter (if any) relative to the frame pointer.
2304 static const int kDisplacement = 2 * kPointerSize; 2307 static const int kDisplacement = 2 * kPointerSize;
2305 2308
2306 // Check if the calling frame is an arguments adaptor frame. 2309 // Check if the calling frame is an arguments adaptor frame.
2307 Label adaptor_frame, try_allocate, runtime; 2310 Label adaptor_frame, try_allocate, runtime;
2308 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2311 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2309 __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset), 2312 __ Cmp(Operand(rdx, StandardFrameConstants::kContextOffset),
2310 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2313 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2311 __ j(equal, &adaptor_frame); 2314 __ j(equal, &adaptor_frame);
2312 2315
2313 // Get the length from the frame. 2316 // Get the length from the frame.
2314 __ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize)); 2317 __ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize));
2315 __ jmp(&try_allocate); 2318 __ jmp(&try_allocate);
2316 2319
2317 // Patch the arguments.length and the parameters pointer. 2320 // Patch the arguments.length and the parameters pointer.
2318 __ bind(&adaptor_frame); 2321 __ bind(&adaptor_frame);
2319 __ SmiToInteger32(rcx, 2322 __ SmiToInteger32(rcx,
2320 Operand(rdx, 2323 Operand(rdx,
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after
4168 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); 4171 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset));
4169 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); 4172 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
4170 } 4173 }
4171 // Get the instance types of the two strings as they will be needed soon. 4174 // Get the instance types of the two strings as they will be needed soon.
4172 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); 4175 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset));
4173 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); 4176 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
4174 4177
4175 // Look at the length of the result of adding the two strings. 4178 // Look at the length of the result of adding the two strings.
4176 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); 4179 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
4177 __ SmiAdd(rbx, rbx, rcx); 4180 __ SmiAdd(rbx, rbx, rcx);
4178 // Use the runtime system when adding two one character strings, as it 4181 // Use the symbol table when adding two one character strings, as it
4179 // contains optimizations for this specific case using the symbol table. 4182 // helps later optimizations to return a symbol here.
4180 __ SmiCompare(rbx, Smi::FromInt(2)); 4183 __ SmiCompare(rbx, Smi::FromInt(2));
4181 __ j(not_equal, &longer_than_two); 4184 __ j(not_equal, &longer_than_two);
4182 4185
4183 // Check that both strings are non-external ascii strings. 4186 // Check that both strings are non-external ascii strings.
4184 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, 4187 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
4185 &string_add_runtime); 4188 &string_add_runtime);
4186 4189
4187 // Get the two characters forming the sub string. 4190 // Get the two characters forming the sub string.
4188 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); 4191 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize));
4189 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); 4192 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize));
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4521 // Load the symbol table. 4524 // Load the symbol table.
4522 Register symbol_table = c2; 4525 Register symbol_table = c2;
4523 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); 4526 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex);
4524 4527
4525 // Calculate capacity mask from the symbol table capacity. 4528 // Calculate capacity mask from the symbol table capacity.
4526 Register mask = scratch2; 4529 Register mask = scratch2;
4527 __ SmiToInteger32(mask, 4530 __ SmiToInteger32(mask,
4528 FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); 4531 FieldOperand(symbol_table, SymbolTable::kCapacityOffset));
4529 __ decl(mask); 4532 __ decl(mask);
4530 4533
4531 Register undefined = scratch4; 4534 Register map = scratch4;
4532 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
4533 4535
4534 // Registers 4536 // Registers
4535 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 4537 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
4536 // hash: hash of two character string (32-bit int) 4538 // hash: hash of two character string (32-bit int)
4537 // symbol_table: symbol table 4539 // symbol_table: symbol table
4538 // mask: capacity mask (32-bit int) 4540 // mask: capacity mask (32-bit int)
4539 // undefined: undefined value 4541 // map: -
4540 // scratch: - 4542 // scratch: -
4541 4543
4542 // Perform a number of probes in the symbol table. 4544 // Perform a number of probes in the symbol table.
4543 static const int kProbes = 4; 4545 static const int kProbes = 4;
4544 Label found_in_symbol_table; 4546 Label found_in_symbol_table;
4545 Label next_probe[kProbes]; 4547 Label next_probe[kProbes];
4546 for (int i = 0; i < kProbes; i++) { 4548 for (int i = 0; i < kProbes; i++) {
4547 // Calculate entry in symbol table. 4549 // Calculate entry in symbol table.
4548 __ movl(scratch, hash); 4550 __ movl(scratch, hash);
4549 if (i > 0) { 4551 if (i > 0) {
4550 __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i))); 4552 __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i)));
4551 } 4553 }
4552 __ andl(scratch, mask); 4554 __ andl(scratch, mask);
4553 4555
4554 // Load the entry from the symble table. 4556 // Load the entry from the symbol table.
4555 Register candidate = scratch; // Scratch register contains candidate. 4557 Register candidate = scratch; // Scratch register contains candidate.
4556 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 4558 STATIC_ASSERT(SymbolTable::kEntrySize == 1);
4557 __ movq(candidate, 4559 __ movq(candidate,
4558 FieldOperand(symbol_table, 4560 FieldOperand(symbol_table,
4559 scratch, 4561 scratch,
4560 times_pointer_size, 4562 times_pointer_size,
4561 SymbolTable::kElementsStartOffset)); 4563 SymbolTable::kElementsStartOffset));
4562 4564
4563 // If entry is undefined no string with this hash can be found. 4565 // If entry is undefined no string with this hash can be found.
4564 __ cmpq(candidate, undefined); 4566 NearLabel is_string;
4567 __ CmpObjectType(candidate, ODDBALL_TYPE, map);
4568 __ j(not_equal, &is_string);
4569
4570 __ CompareRoot(candidate, Heap::kUndefinedValueRootIndex);
4565 __ j(equal, not_found); 4571 __ j(equal, not_found);
4572 // Must be null (deleted entry).
4573 __ jmp(&next_probe[i]);
4574
4575 __ bind(&is_string);
4566 4576
4567 // If length is not 2 the string is not a candidate. 4577 // If length is not 2 the string is not a candidate.
4568 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset), 4578 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
4569 Smi::FromInt(2)); 4579 Smi::FromInt(2));
4570 __ j(not_equal, &next_probe[i]); 4580 __ j(not_equal, &next_probe[i]);
4571 4581
4572 // We use kScratchRegister as a temporary register in assumption that 4582 // We use kScratchRegister as a temporary register in assumption that
4573 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly 4583 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
4574 Register temp = kScratchRegister; 4584 Register temp = kScratchRegister;
4575 4585
4576 // Check that the candidate is a non-external ascii string. 4586 // Check that the candidate is a non-external ascii string.
4577 __ movq(temp, FieldOperand(candidate, HeapObject::kMapOffset)); 4587 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset));
4578 __ movzxbl(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
4579 __ JumpIfInstanceTypeIsNotSequentialAscii( 4588 __ JumpIfInstanceTypeIsNotSequentialAscii(
4580 temp, temp, &next_probe[i]); 4589 temp, temp, &next_probe[i]);
4581 4590
4582 // Check if the two characters match. 4591 // Check if the two characters match.
4583 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); 4592 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize));
4584 __ andl(temp, Immediate(0x0000ffff)); 4593 __ andl(temp, Immediate(0x0000ffff));
4585 __ cmpl(chars, temp); 4594 __ cmpl(chars, temp);
4586 __ j(equal, &found_in_symbol_table); 4595 __ j(equal, &found_in_symbol_table);
4587 __ bind(&next_probe[i]); 4596 __ bind(&next_probe[i]);
4588 } 4597 }
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4920 __ push(rcx); 4929 __ push(rcx);
4921 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8); 4930 GenerateCompareFlatAsciiStrings(masm, rdx, rax, rcx, rbx, rdi, r8);
4922 4931
4923 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 4932 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
4924 // tagged as a small integer. 4933 // tagged as a small integer.
4925 __ bind(&runtime); 4934 __ bind(&runtime);
4926 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 4935 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
4927 } 4936 }
4928 4937
4929 4938
4930 void StringCharAtStub::Generate(MacroAssembler* masm) {
4931 // Expects two arguments (object, index) on the stack:
4932
4933 // Stack frame on entry.
4934 // rsp[0]: return address
4935 // rsp[8]: index
4936 // rsp[16]: object
4937
4938 Register object = rbx;
4939 Register index = rax;
4940 Register scratch1 = rcx;
4941 Register scratch2 = rdx;
4942 Register result = rax;
4943
4944 __ pop(scratch1); // Return address.
4945 __ pop(index);
4946 __ pop(object);
4947 __ push(scratch1);
4948
4949 Label need_conversion;
4950 Label index_out_of_range;
4951 Label done;
4952 StringCharAtGenerator generator(object,
4953 index,
4954 scratch1,
4955 scratch2,
4956 result,
4957 &need_conversion,
4958 &need_conversion,
4959 &index_out_of_range,
4960 STRING_INDEX_IS_NUMBER);
4961 generator.GenerateFast(masm);
4962 __ jmp(&done);
4963
4964 __ bind(&index_out_of_range);
4965 // When the index is out of range, the spec requires us to return
4966 // the empty string.
4967 __ LoadRoot(result, Heap::kEmptyStringRootIndex);
4968 __ jmp(&done);
4969
4970 __ bind(&need_conversion);
4971 // Move smi zero into the result register, which will trigger
4972 // conversion.
4973 __ Move(result, Smi::FromInt(0));
4974 __ jmp(&done);
4975
4976 StubRuntimeCallHelper call_helper;
4977 generator.GenerateSlow(masm, call_helper);
4978
4979 __ bind(&done);
4980 __ ret(0);
4981 }
4982
4983
4984 void ICCompareStub::GenerateSmis(MacroAssembler* masm) { 4939 void ICCompareStub::GenerateSmis(MacroAssembler* masm) {
4985 ASSERT(state_ == CompareIC::SMIS); 4940 ASSERT(state_ == CompareIC::SMIS);
4986 NearLabel miss; 4941 NearLabel miss;
4987 __ JumpIfNotBothSmi(rdx, rax, &miss); 4942 __ JumpIfNotBothSmi(rdx, rax, &miss);
4988 4943
4989 if (GetCondition() == equal) { 4944 if (GetCondition() == equal) {
4990 // For equality we do not care about the sign of the result. 4945 // For equality we do not care about the sign of the result.
4991 __ subq(rax, rdx); 4946 __ subq(rax, rdx);
4992 } else { 4947 } else {
4993 NearLabel done; 4948 NearLabel done;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
5096 // Do a tail call to the rewritten stub. 5051 // Do a tail call to the rewritten stub.
5097 __ jmp(rdi); 5052 __ jmp(rdi);
5098 } 5053 }
5099 5054
5100 5055
5101 #undef __ 5056 #undef __
5102 5057
5103 } } // namespace v8::internal 5058 } } // namespace v8::internal
5104 5059
5105 #endif // V8_TARGET_ARCH_X64 5060 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698