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

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

Issue 6682026: Fix SmiCompare on 64 bit to distinguish between comparisons where... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' 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
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 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 2237
2238 // The displacement is used for skipping the frame pointer on the 2238 // The displacement is used for skipping the frame pointer on the
2239 // stack. It is the offset of the last parameter (if any) relative 2239 // stack. It is the offset of the last parameter (if any) relative
2240 // to the frame pointer. 2240 // to the frame pointer.
2241 static const int kDisplacement = 1 * kPointerSize; 2241 static const int kDisplacement = 1 * kPointerSize;
2242 2242
2243 // Check that the key is a smi. 2243 // Check that the key is a smi.
2244 Label slow; 2244 Label slow;
2245 __ JumpIfNotSmi(rdx, &slow); 2245 __ JumpIfNotSmi(rdx, &slow);
2246 2246
2247 // Check if the calling frame is an arguments adaptor frame. 2247 // Check if the calling frame is an arguments adaptor frame. We look at the
2248 // context offset, and if the frame is not a regular one, then we find a
2249 // Smi instead of the context. We can't use SmiCompare here, because that
2250 // only works for comparing two smis.
2248 Label adaptor; 2251 Label adaptor;
2249 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2252 __ movq(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2250 __ SmiCompare(Operand(rbx, StandardFrameConstants::kContextOffset), 2253 __ Cmp(Operand(rbx, StandardFrameConstants::kContextOffset),
2251 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2254 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2252 __ j(equal, &adaptor); 2255 __ j(equal, &adaptor);
2253 2256
2254 // Check index against formal parameters count limit passed in 2257 // Check index against formal parameters count limit passed in
2255 // through register rax. Use unsigned comparison to get negative 2258 // through register rax. Use unsigned comparison to get negative
2256 // check for free. 2259 // check for free.
2257 __ cmpq(rdx, rax); 2260 __ cmpq(rdx, rax);
2258 __ j(above_equal, &slow); 2261 __ j(above_equal, &slow);
2259 2262
2260 // Read the argument from the stack and return it. 2263 // Read the argument from the stack and return it.
2261 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2); 2264 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2296 // rsp[24] : function 2299 // rsp[24] : function
2297 2300
2298 // The displacement is used for skipping the return address and the 2301 // The displacement is used for skipping the return address and the
2299 // frame pointer on the stack. It is the offset of the last 2302 // frame pointer on the stack. It is the offset of the last
2300 // parameter (if any) relative to the frame pointer. 2303 // parameter (if any) relative to the frame pointer.
2301 static const int kDisplacement = 2 * kPointerSize; 2304 static const int kDisplacement = 2 * kPointerSize;
2302 2305
2303 // Check if the calling frame is an arguments adaptor frame. 2306 // Check if the calling frame is an arguments adaptor frame.
2304 Label adaptor_frame, try_allocate, runtime; 2307 Label adaptor_frame, try_allocate, runtime;
2305 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset)); 2308 __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
2306 __ SmiCompare(Operand(rdx, StandardFrameConstants::kContextOffset), 2309 __ Cmp(Operand(rdx, StandardFrameConstants::kContextOffset),
2307 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); 2310 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
2308 __ j(equal, &adaptor_frame); 2311 __ j(equal, &adaptor_frame);
2309 2312
2310 // Get the length from the frame. 2313 // Get the length from the frame.
2311 __ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize)); 2314 __ SmiToInteger32(rcx, Operand(rsp, 1 * kPointerSize));
2312 __ jmp(&try_allocate); 2315 __ jmp(&try_allocate);
2313 2316
2314 // Patch the arguments.length and the parameters pointer. 2317 // Patch the arguments.length and the parameters pointer.
2315 __ bind(&adaptor_frame); 2318 __ bind(&adaptor_frame);
2316 __ SmiToInteger32(rcx, 2319 __ SmiToInteger32(rcx,
2317 Operand(rdx, 2320 Operand(rdx,
(...skipping 1832 matching lines...) Expand 10 before | Expand all | Expand 10 after
4150 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset)); 4153 __ movq(r8, FieldOperand(rax, HeapObject::kMapOffset));
4151 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset)); 4154 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
4152 } 4155 }
4153 // Get the instance types of the two strings as they will be needed soon. 4156 // Get the instance types of the two strings as they will be needed soon.
4154 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset)); 4157 __ movzxbl(r8, FieldOperand(r8, Map::kInstanceTypeOffset));
4155 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset)); 4158 __ movzxbl(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
4156 4159
4157 // Look at the length of the result of adding the two strings. 4160 // Look at the length of the result of adding the two strings.
4158 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2); 4161 STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue / 2);
4159 __ SmiAdd(rbx, rbx, rcx); 4162 __ SmiAdd(rbx, rbx, rcx);
4160 // Use the runtime system when adding two one character strings, as it 4163 // Use the symbol table when adding two one character strings, as it
4161 // contains optimizations for this specific case using the symbol table. 4164 // helps later optimizations to return a symbol here.
4162 __ SmiCompare(rbx, Smi::FromInt(2)); 4165 __ SmiCompare(rbx, Smi::FromInt(2));
4163 __ j(not_equal, &longer_than_two); 4166 __ j(not_equal, &longer_than_two);
4164 4167
4165 // Check that both strings are non-external ascii strings. 4168 // Check that both strings are non-external ascii strings.
4166 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, 4169 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
4167 &string_add_runtime); 4170 &string_add_runtime);
4168 4171
4169 // Get the two characters forming the sub string. 4172 // Get the two characters forming the sub string.
4170 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); 4173 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize));
4171 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); 4174 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize));
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
4503 // Load the symbol table. 4506 // Load the symbol table.
4504 Register symbol_table = c2; 4507 Register symbol_table = c2;
4505 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); 4508 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex);
4506 4509
4507 // Calculate capacity mask from the symbol table capacity. 4510 // Calculate capacity mask from the symbol table capacity.
4508 Register mask = scratch2; 4511 Register mask = scratch2;
4509 __ SmiToInteger32(mask, 4512 __ SmiToInteger32(mask,
4510 FieldOperand(symbol_table, SymbolTable::kCapacityOffset)); 4513 FieldOperand(symbol_table, SymbolTable::kCapacityOffset));
4511 __ decl(mask); 4514 __ decl(mask);
4512 4515
4513 Register undefined = scratch4; 4516 Register map = scratch4;
4514 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
4515 4517
4516 // Registers 4518 // Registers
4517 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. 4519 // chars: two character string, char 1 in byte 0 and char 2 in byte 1.
4518 // hash: hash of two character string (32-bit int) 4520 // hash: hash of two character string (32-bit int)
4519 // symbol_table: symbol table 4521 // symbol_table: symbol table
4520 // mask: capacity mask (32-bit int) 4522 // mask: capacity mask (32-bit int)
4521 // undefined: undefined value 4523 // map: -
4522 // scratch: - 4524 // scratch: -
4523 4525
4524 // Perform a number of probes in the symbol table. 4526 // Perform a number of probes in the symbol table.
4525 static const int kProbes = 4; 4527 static const int kProbes = 4;
4526 Label found_in_symbol_table; 4528 Label found_in_symbol_table;
4527 Label next_probe[kProbes]; 4529 Label next_probe[kProbes];
4528 for (int i = 0; i < kProbes; i++) { 4530 for (int i = 0; i < kProbes; i++) {
4529 // Calculate entry in symbol table. 4531 // Calculate entry in symbol table.
4530 __ movl(scratch, hash); 4532 __ movl(scratch, hash);
4531 if (i > 0) { 4533 if (i > 0) {
4532 __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i))); 4534 __ addl(scratch, Immediate(SymbolTable::GetProbeOffset(i)));
4533 } 4535 }
4534 __ andl(scratch, mask); 4536 __ andl(scratch, mask);
4535 4537
4536 // Load the entry from the symble table. 4538 // Load the entry from the symbol table.
4537 Register candidate = scratch; // Scratch register contains candidate. 4539 Register candidate = scratch; // Scratch register contains candidate.
4538 STATIC_ASSERT(SymbolTable::kEntrySize == 1); 4540 STATIC_ASSERT(SymbolTable::kEntrySize == 1);
4539 __ movq(candidate, 4541 __ movq(candidate,
4540 FieldOperand(symbol_table, 4542 FieldOperand(symbol_table,
4541 scratch, 4543 scratch,
4542 times_pointer_size, 4544 times_pointer_size,
4543 SymbolTable::kElementsStartOffset)); 4545 SymbolTable::kElementsStartOffset));
4544 4546
4545 // If entry is undefined no string with this hash can be found. 4547 // If entry is undefined no string with this hash can be found.
4546 __ cmpq(candidate, undefined); 4548 NearLabel is_string;
4549 __ CmpObjectType(candidate, ODDBALL_TYPE, map);
4550 __ j(not_equal, &is_string);
4551
4552 __ CompareRoot(candidate, Heap::kUndefinedValueRootIndex);
4547 __ j(equal, not_found); 4553 __ j(equal, not_found);
4554 // Must be null (deleted entry).
4555 __ jmp(&next_probe[i]);
4556
4557 __ bind(&is_string);
4548 4558
4549 // If length is not 2 the string is not a candidate. 4559 // If length is not 2 the string is not a candidate.
4550 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset), 4560 __ SmiCompare(FieldOperand(candidate, String::kLengthOffset),
4551 Smi::FromInt(2)); 4561 Smi::FromInt(2));
4552 __ j(not_equal, &next_probe[i]); 4562 __ j(not_equal, &next_probe[i]);
4553 4563
4554 // We use kScratchRegister as a temporary register in assumption that 4564 // We use kScratchRegister as a temporary register in assumption that
4555 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly 4565 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
4556 Register temp = kScratchRegister; 4566 Register temp = kScratchRegister;
4557 4567
4558 // Check that the candidate is a non-external ascii string. 4568 // Check that the candidate is a non-external ascii string.
4559 __ movq(temp, FieldOperand(candidate, HeapObject::kMapOffset)); 4569 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset));
4560 __ movzxbl(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
4561 __ JumpIfInstanceTypeIsNotSequentialAscii( 4570 __ JumpIfInstanceTypeIsNotSequentialAscii(
4562 temp, temp, &next_probe[i]); 4571 temp, temp, &next_probe[i]);
4563 4572
4564 // Check if the two characters match. 4573 // Check if the two characters match.
4565 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); 4574 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize));
4566 __ andl(temp, Immediate(0x0000ffff)); 4575 __ andl(temp, Immediate(0x0000ffff));
4567 __ cmpl(chars, temp); 4576 __ cmpl(chars, temp);
4568 __ j(equal, &found_in_symbol_table); 4577 __ j(equal, &found_in_symbol_table);
4569 __ bind(&next_probe[i]); 4578 __ bind(&next_probe[i]);
4570 } 4579 }
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
5078 // Do a tail call to the rewritten stub. 5087 // Do a tail call to the rewritten stub.
5079 __ jmp(rdi); 5088 __ jmp(rdi);
5080 } 5089 }
5081 5090
5082 5091
5083 #undef __ 5092 #undef __
5084 5093
5085 } } // namespace v8::internal 5094 } } // namespace v8::internal
5086 5095
5087 #endif // V8_TARGET_ARCH_X64 5096 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698