OLD | NEW |
---|---|
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 5942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5953 __ orr(chars, chars, Operand(c2, LSL, kBitsPerByte)); | 5953 __ orr(chars, chars, Operand(c2, LSL, kBitsPerByte)); |
5954 | 5954 |
5955 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. | 5955 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
5956 // hash: hash of two character string. | 5956 // hash: hash of two character string. |
5957 | 5957 |
5958 // Load symbol table | 5958 // Load symbol table |
5959 // Load address of first element of the symbol table. | 5959 // Load address of first element of the symbol table. |
5960 Register symbol_table = c2; | 5960 Register symbol_table = c2; |
5961 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); | 5961 __ LoadRoot(symbol_table, Heap::kSymbolTableRootIndex); |
5962 | 5962 |
5963 // Load undefined value | |
5964 Register undefined = scratch4; | 5963 Register undefined = scratch4; |
5965 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); | 5964 __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex); |
5966 | 5965 |
5967 // Calculate capacity mask from the symbol table capacity. | 5966 // Calculate capacity mask from the symbol table capacity. |
5968 Register mask = scratch2; | 5967 Register mask = scratch2; |
5969 __ ldr(mask, FieldMemOperand(symbol_table, SymbolTable::kCapacityOffset)); | 5968 __ ldr(mask, FieldMemOperand(symbol_table, SymbolTable::kCapacityOffset)); |
5970 __ mov(mask, Operand(mask, ASR, 1)); | 5969 __ mov(mask, Operand(mask, ASR, 1)); |
5971 __ sub(mask, mask, Operand(1)); | 5970 __ sub(mask, mask, Operand(1)); |
5972 | 5971 |
5973 // Calculate untagged address of the first element of the symbol table. | 5972 // Calculate untagged address of the first element of the symbol table. |
5974 Register first_symbol_table_element = symbol_table; | 5973 Register first_symbol_table_element = symbol_table; |
5975 __ add(first_symbol_table_element, symbol_table, | 5974 __ add(first_symbol_table_element, symbol_table, |
5976 Operand(SymbolTable::kElementsStartOffset - kHeapObjectTag)); | 5975 Operand(SymbolTable::kElementsStartOffset - kHeapObjectTag)); |
5977 | 5976 |
5978 // Registers | 5977 // Registers |
5979 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. | 5978 // chars: two character string, char 1 in byte 0 and char 2 in byte 1. |
5980 // hash: hash of two character string | 5979 // hash: hash of two character string |
5981 // mask: capacity mask | 5980 // mask: capacity mask |
5982 // first_symbol_table_element: address of the first element of | 5981 // first_symbol_table_element: address of the first element of |
5983 // the symbol table | 5982 // the symbol table |
5983 // undefined: the undefined object | |
5984 // scratch: - | 5984 // scratch: - |
5985 | 5985 |
5986 // Perform a number of probes in the symbol table. | 5986 // Perform a number of probes in the symbol table. |
5987 static const int kProbes = 4; | 5987 static const int kProbes = 4; |
5988 Label found_in_symbol_table; | 5988 Label found_in_symbol_table; |
5989 Label next_probe[kProbes]; | 5989 Label next_probe[kProbes]; |
5990 for (int i = 0; i < kProbes; i++) { | 5990 for (int i = 0; i < kProbes; i++) { |
5991 Register candidate = scratch5; // Scratch register contains candidate. | 5991 Register candidate = scratch5; // Scratch register contains candidate. |
5992 | 5992 |
5993 // Calculate entry in symbol table. | 5993 // Calculate entry in symbol table. |
5994 if (i > 0) { | 5994 if (i > 0) { |
5995 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); | 5995 __ add(candidate, hash, Operand(SymbolTable::GetProbeOffset(i))); |
5996 } else { | 5996 } else { |
5997 __ mov(candidate, hash); | 5997 __ mov(candidate, hash); |
5998 } | 5998 } |
5999 | 5999 |
6000 __ and_(candidate, candidate, Operand(mask)); | 6000 __ and_(candidate, candidate, Operand(mask)); |
6001 | 6001 |
6002 // Load the entry from the symble table. | 6002 // Load the entry from the symble table. |
6003 STATIC_ASSERT(SymbolTable::kEntrySize == 1); | 6003 STATIC_ASSERT(SymbolTable::kEntrySize == 1); |
6004 __ ldr(candidate, | 6004 __ ldr(candidate, |
6005 MemOperand(first_symbol_table_element, | 6005 MemOperand(first_symbol_table_element, |
6006 candidate, | 6006 candidate, |
6007 LSL, | 6007 LSL, |
6008 kPointerSizeLog2)); | 6008 kPointerSizeLog2)); |
6009 | 6009 |
6010 // If entry is undefined no string with this hash can be found. | 6010 // If entry is undefined no string with this hash can be found. |
6011 __ cmp(candidate, undefined); | 6011 Label is_string; |
6012 __ CompareObjectType(candidate, scratch, scratch, ODDBALL_TYPE); | |
6013 __ b(ne, &is_string); | |
6014 | |
6015 __ cmp(undefined, candidate); | |
6012 __ b(eq, not_found); | 6016 __ b(eq, not_found); |
6017 // Must be null (deleted entry). | |
Lasse Reichstein
2011/03/15 09:07:01
How about adding some debug code to test that it i
Erik Corry
2011/03/15 10:00:50
Done.
| |
6018 __ jmp(&next_probe[i]); | |
6019 | |
6020 __ bind(&is_string); | |
6021 | |
6022 // Check that the candidate is a non-external ascii string. The instance | |
Lasse Reichstein
2011/03/15 09:07:01
ASCII is an acronym.
Erik Corry
2011/03/15 10:00:50
Done.
| |
6023 // type is still in the scratch register from the CompareObjectType | |
6024 // operation. | |
6025 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, &next_probe[i]); | |
6013 | 6026 |
6014 // If length is not 2 the string is not a candidate. | 6027 // If length is not 2 the string is not a candidate. |
6015 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset)); | 6028 __ ldr(scratch, FieldMemOperand(candidate, String::kLengthOffset)); |
6016 __ cmp(scratch, Operand(Smi::FromInt(2))); | 6029 __ cmp(scratch, Operand(Smi::FromInt(2))); |
6017 __ b(ne, &next_probe[i]); | 6030 __ b(ne, &next_probe[i]); |
6018 | 6031 |
6019 // Check that the candidate is a non-external ascii string. | |
6020 __ ldr(scratch, FieldMemOperand(candidate, HeapObject::kMapOffset)); | |
6021 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset)); | |
6022 __ JumpIfInstanceTypeIsNotSequentialAscii(scratch, scratch, | |
6023 &next_probe[i]); | |
6024 | |
6025 // Check if the two characters match. | 6032 // Check if the two characters match. |
6026 // Assumes that word load is little endian. | 6033 // Assumes that word load is little endian. |
6027 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize)); | 6034 __ ldrh(scratch, FieldMemOperand(candidate, SeqAsciiString::kHeaderSize)); |
6028 __ cmp(chars, scratch); | 6035 __ cmp(chars, scratch); |
6029 __ b(eq, &found_in_symbol_table); | 6036 __ b(eq, &found_in_symbol_table); |
6030 __ bind(&next_probe[i]); | 6037 __ bind(&next_probe[i]); |
6031 } | 6038 } |
6032 | 6039 |
6033 // No matching 2 character string found by probing. | 6040 // No matching 2 character string found by probing. |
6034 __ jmp(not_found); | 6041 __ jmp(not_found); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6441 // r1: second string | 6448 // r1: second string |
6442 // r2: length of first string | 6449 // r2: length of first string |
6443 // r3: length of second string | 6450 // r3: length of second string |
6444 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) | 6451 // r4: first string instance type (if flags_ == NO_STRING_ADD_FLAGS) |
6445 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) | 6452 // r5: second string instance type (if flags_ == NO_STRING_ADD_FLAGS) |
6446 // Look at the length of the result of adding the two strings. | 6453 // Look at the length of the result of adding the two strings. |
6447 Label string_add_flat_result, longer_than_two; | 6454 Label string_add_flat_result, longer_than_two; |
6448 // Adding two lengths can't overflow. | 6455 // Adding two lengths can't overflow. |
6449 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2); | 6456 STATIC_ASSERT(String::kMaxLength < String::kMaxLength * 2); |
6450 __ add(r6, r2, Operand(r3)); | 6457 __ add(r6, r2, Operand(r3)); |
6451 // Use the runtime system when adding two one character strings, as it | 6458 // Use the symbol table when adding two one character strings, as it |
6452 // contains optimizations for this specific case using the symbol table. | 6459 // helps later optimizations to return a symbol here. |
6453 __ cmp(r6, Operand(2)); | 6460 __ cmp(r6, Operand(2)); |
6454 __ b(ne, &longer_than_two); | 6461 __ b(ne, &longer_than_two); |
6455 | 6462 |
6456 // Check that both strings are non-external ascii strings. | 6463 // Check that both strings are non-external ascii strings. |
6457 if (flags_ != NO_STRING_ADD_FLAGS) { | 6464 if (flags_ != NO_STRING_ADD_FLAGS) { |
6458 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); | 6465 __ ldr(r4, FieldMemOperand(r0, HeapObject::kMapOffset)); |
6459 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); | 6466 __ ldr(r5, FieldMemOperand(r1, HeapObject::kMapOffset)); |
6460 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); | 6467 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); |
6461 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); | 6468 __ ldrb(r5, FieldMemOperand(r5, Map::kInstanceTypeOffset)); |
6462 } | 6469 } |
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6898 __ str(pc, MemOperand(sp, 0)); | 6905 __ str(pc, MemOperand(sp, 0)); |
6899 __ Jump(target); // Call the C++ function. | 6906 __ Jump(target); // Call the C++ function. |
6900 } | 6907 } |
6901 | 6908 |
6902 | 6909 |
6903 #undef __ | 6910 #undef __ |
6904 | 6911 |
6905 } } // namespace v8::internal | 6912 } } // namespace v8::internal |
6906 | 6913 |
6907 #endif // V8_TARGET_ARCH_ARM | 6914 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |