| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 24 matching lines...) Expand all Loading... |
| 35 namespace v8 { namespace internal { | 35 namespace v8 { namespace internal { |
| 36 | 36 |
| 37 // ---------------------------------------------------------------------------- | 37 // ---------------------------------------------------------------------------- |
| 38 // Static IC stub generators. | 38 // Static IC stub generators. |
| 39 // | 39 // |
| 40 | 40 |
| 41 #define __ masm-> | 41 #define __ masm-> |
| 42 | 42 |
| 43 | 43 |
| 44 // Helper function used to load a property from a dictionary backing storage. | 44 // Helper function used to load a property from a dictionary backing storage. |
| 45 // This function may return false negatives, so miss_label |
| 46 // must always call a backup property load that is complete. |
| 47 // This function is safe to call if the receiver has fast properties, |
| 48 // or if name is not a symbol, and will jump to the miss_label in that case. |
| 45 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, | 49 static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, |
| 46 Register r0, Register r1, Register r2, | 50 Register r0, Register r1, Register r2, |
| 47 Register name) { | 51 Register name) { |
| 48 // Register use: | 52 // Register use: |
| 49 // | 53 // |
| 50 // r0 - used to hold the property dictionary. | 54 // r0 - used to hold the property dictionary. |
| 51 // | 55 // |
| 52 // r1 - initially the receiver | 56 // r1 - initially the receiver |
| 53 // - used for the index into the property dictionary | 57 // - used for the index into the property dictionary |
| 54 // - holds the result on exit. | 58 // - holds the result on exit. |
| 55 // | 59 // |
| 56 // r2 - used to hold the capacity of the property dictionary. | 60 // r2 - used to hold the capacity of the property dictionary. |
| 57 // | 61 // |
| 58 // name - holds the name of the property and is unchanges. | 62 // name - holds the name of the property and is unchanged. |
| 59 | 63 |
| 60 Label done; | 64 Label done; |
| 61 | 65 |
| 62 // Check for the absence of an interceptor. | 66 // Check for the absence of an interceptor. |
| 63 // Load the map into r0. | 67 // Load the map into r0. |
| 64 __ mov(r0, FieldOperand(r1, JSObject::kMapOffset)); | 68 __ mov(r0, FieldOperand(r1, JSObject::kMapOffset)); |
| 65 // Test the has_named_interceptor bit in the map. | 69 // Test the has_named_interceptor bit in the map. |
| 66 __ test(FieldOperand(r0, Map::kInstanceAttributesOffset), | 70 __ test(FieldOperand(r0, Map::kInstanceAttributesOffset), |
| 67 Immediate(1 << (Map::kHasNamedInterceptor + (3 * 8)))); | 71 Immediate(1 << (Map::kHasNamedInterceptor + (3 * 8)))); |
| 68 // Jump to miss if the interceptor bit is set. | 72 // Jump to miss if the interceptor bit is set. |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), | 252 __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), |
| 249 Immediate(Factory::hash_table_map())); | 253 Immediate(Factory::hash_table_map())); |
| 250 __ j(equal, &slow, not_taken); | 254 __ j(equal, &slow, not_taken); |
| 251 // Check that the key (index) is within bounds. | 255 // Check that the key (index) is within bounds. |
| 252 __ cmp(eax, FieldOperand(ecx, Array::kLengthOffset)); | 256 __ cmp(eax, FieldOperand(ecx, Array::kLengthOffset)); |
| 253 __ j(below, &fast, taken); | 257 __ j(below, &fast, taken); |
| 254 // Slow case: Load name and receiver from stack and jump to runtime. | 258 // Slow case: Load name and receiver from stack and jump to runtime. |
| 255 __ bind(&slow); | 259 __ bind(&slow); |
| 256 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); | 260 __ IncrementCounter(&Counters::keyed_load_generic_slow, 1); |
| 257 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); | 261 KeyedLoadIC::Generate(masm, ExternalReference(Runtime::kKeyedGetProperty)); |
| 258 // Check if the key is a symbol that is not an array index. | 262 |
| 259 __ bind(&check_string); | 263 __ bind(&check_string); |
| 264 // The key is not a smi. |
| 265 // Is it a string? |
| 266 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edx); |
| 267 __ j(above_equal, &slow); |
| 268 // Is the string an array index, with cached numeric value? |
| 260 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); | 269 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); |
| 261 __ test(ebx, Immediate(String::kIsArrayIndexMask)); | 270 __ test(ebx, Immediate(String::kIsArrayIndexMask)); |
| 262 __ j(not_zero, &index_string, not_taken); | 271 __ j(not_zero, &index_string, not_taken); |
| 263 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 272 |
| 264 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 273 // If the string is a symbol, do a quick inline probe of the receiver's |
| 274 // dictionary, if it exists. |
| 275 __ movzx_b(ebx, FieldOperand(edx, Map::kInstanceTypeOffset)); |
| 265 __ test(ebx, Immediate(kIsSymbolMask)); | 276 __ test(ebx, Immediate(kIsSymbolMask)); |
| 266 __ j(not_zero, &slow, not_taken); | 277 __ j(zero, &slow, not_taken); |
| 267 // Probe the dictionary leaving result in ecx. | 278 // Probe the dictionary leaving result in ecx. |
| 268 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); | 279 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); |
| 269 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx); | 280 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx); |
| 270 __ mov(eax, Operand(ecx)); | 281 __ mov(eax, Operand(ecx)); |
| 271 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); | 282 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); |
| 272 __ ret(0); | 283 __ ret(0); |
| 273 // Array index string: If short enough use cache in length/hash field (ebx). | 284 // Array index string: If short enough use cache in length/hash field (ebx). |
| 274 // We assert that there are enough bits in an int32_t after the hash shift | 285 // We assert that there are enough bits in an int32_t after the hash shift |
| 275 // bits have been subtracted to allow space for the length and the cached | 286 // bits have been subtracted to allow space for the length and the cached |
| 276 // array index. | 287 // array index. |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 | 894 |
| 884 // Do tail-call to runtime routine. | 895 // Do tail-call to runtime routine. |
| 885 __ TailCallRuntime( | 896 __ TailCallRuntime( |
| 886 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); | 897 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); |
| 887 } | 898 } |
| 888 | 899 |
| 889 #undef __ | 900 #undef __ |
| 890 | 901 |
| 891 | 902 |
| 892 } } // namespace v8::internal | 903 } } // namespace v8::internal |
| OLD | NEW |