Chromium Code Reviews| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag), | 116 __ test(Operand(r0, r1, times_4, kDetailsOffset - kHeapObjectTag), |
| 117 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); | 117 Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); |
| 118 __ j(not_zero, miss_label, not_taken); | 118 __ j(not_zero, miss_label, not_taken); |
| 119 | 119 |
| 120 // Get the value at the masked, scaled index. | 120 // Get the value at the masked, scaled index. |
| 121 const int kValueOffset = kElementsStartOffset + kPointerSize; | 121 const int kValueOffset = kElementsStartOffset + kPointerSize; |
| 122 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag)); | 122 __ mov(r1, Operand(r0, r1, times_4, kValueOffset - kHeapObjectTag)); |
| 123 } | 123 } |
| 124 | 124 |
| 125 | 125 |
| 126 // Helper function used to check that a value is either not a function | 126 // Helper function used to check that a value is either not an object |
| 127 // or is loaded if it is a function. | 127 // or is loaded if it is an object. |
| 128 static void GenerateCheckNonFunctionOrLoaded(MacroAssembler* masm, Label* miss, | 128 static void GenerateCheckNonObjectOrLoaded(MacroAssembler* masm, Label* miss, |
| 129 Register value, Register scratch) { | 129 Register value, Register scratch) { |
| 130 Label done; | 130 Label done; |
| 131 // Check if the value is a Smi. | 131 // Check if the value is a Smi. |
| 132 __ test(value, Immediate(kSmiTagMask)); | 132 __ test(value, Immediate(kSmiTagMask)); |
| 133 __ j(zero, &done, not_taken); | 133 __ j(zero, &done, not_taken); |
| 134 // Check if the value is a function. | 134 // Check if the object has been loaded. |
| 135 __ CmpObjectType(value, JS_FUNCTION_TYPE, scratch); | 135 __ mov(scratch, FieldOperand(value, JSFunction::kMapOffset)); |
| 136 __ j(not_equal, &done, taken); | 136 __ mov(scratch, FieldOperand(scratch, Map::kBitField2Offset)); |
| 137 // Check if the function has been loaded. | 137 __ test(scratch, Immediate(1 << Map::kNeedsLoading)); |
| 138 __ mov(scratch, FieldOperand(value, JSFunction::kSharedFunctionInfoOffset)); | 138 __ j(not_zero, miss, not_taken); |
| 139 __ mov(scratch, | |
| 140 FieldOperand(scratch, SharedFunctionInfo::kLazyLoadDataOffset)); | |
| 141 __ cmp(scratch, Factory::undefined_value()); | |
| 142 __ j(not_equal, miss, not_taken); | |
| 143 __ bind(&done); | 139 __ bind(&done); |
| 144 } | 140 } |
| 145 | 141 |
| 146 | 142 |
| 147 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { | 143 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { |
| 148 // ----------- S t a t e ------------- | 144 // ----------- S t a t e ------------- |
| 149 // -- ecx : name | 145 // -- ecx : name |
| 150 // -- esp[0] : return address | 146 // -- esp[0] : return address |
| 151 // -- esp[4] : receiver | 147 // -- esp[4] : receiver |
| 152 // ----------------------------------- | 148 // ----------------------------------- |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 __ bind(&check_string); | 257 __ bind(&check_string); |
| 262 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); | 258 __ mov(ebx, FieldOperand(eax, String::kLengthOffset)); |
| 263 __ test(ebx, Immediate(String::kIsArrayIndexMask)); | 259 __ test(ebx, Immediate(String::kIsArrayIndexMask)); |
| 264 __ j(not_zero, &index_string, not_taken); | 260 __ j(not_zero, &index_string, not_taken); |
| 265 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 261 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 266 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 262 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 267 __ test(ebx, Immediate(kIsSymbolMask)); | 263 __ test(ebx, Immediate(kIsSymbolMask)); |
| 268 __ j(not_zero, &slow, not_taken); | 264 __ j(not_zero, &slow, not_taken); |
| 269 // Probe the dictionary leaving result in ecx. | 265 // Probe the dictionary leaving result in ecx. |
| 270 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); | 266 GenerateDictionaryLoad(masm, &slow, ebx, ecx, edx, eax); |
| 271 GenerateCheckNonFunctionOrLoaded(masm, &slow, ecx, edx); | 267 GenerateCheckNonObjectOrLoaded(masm, &slow, ecx, edx); |
| 272 __ mov(eax, Operand(ecx)); | 268 __ mov(eax, Operand(ecx)); |
| 273 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); | 269 __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1); |
| 274 __ ret(0); | 270 __ ret(0); |
| 275 // Array index string: If short enough use cache in length/hash field (ebx). | 271 // Array index string: If short enough use cache in length/hash field (ebx). |
| 276 // We assert that there are enough bits in an int32_t after the hash shift | 272 // We assert that there are enough bits in an int32_t after the hash shift |
| 277 // bits have been subtracted to allow space for the length and the cached | 273 // bits have been subtracted to allow space for the length and the cached |
| 278 // array index. | 274 // array index. |
| 279 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 275 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
| 280 (1 << (String::kShortLengthShift - String::kHashShift))); | 276 (1 << (String::kShortLengthShift - String::kHashShift))); |
| 281 __ bind(&index_string); | 277 __ bind(&index_string); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 bool is_global_object, | 477 bool is_global_object, |
| 482 Label* miss) { | 478 Label* miss) { |
| 483 // Search dictionary - put result in register edx. | 479 // Search dictionary - put result in register edx. |
| 484 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx); | 480 GenerateDictionaryLoad(masm, miss, eax, edx, ebx, ecx); |
| 485 | 481 |
| 486 // Move the result to register edi and check that it isn't a smi. | 482 // Move the result to register edi and check that it isn't a smi. |
| 487 __ mov(edi, Operand(edx)); | 483 __ mov(edi, Operand(edx)); |
| 488 __ test(edx, Immediate(kSmiTagMask)); | 484 __ test(edx, Immediate(kSmiTagMask)); |
| 489 __ j(zero, miss, not_taken); | 485 __ j(zero, miss, not_taken); |
| 490 | 486 |
| 491 // Check that the value is a JavaScript function. | 487 // Check that the object has been loaded. |
|
Mads Ager (chromium)
2009/04/23 19:09:25
You are removing a JSFunction check here - you sho
| |
| 492 __ CmpObjectType(edx, JS_FUNCTION_TYPE, edx); | 488 __ mov(edx, FieldOperand(edi, JSFunction::kMapOffset)); |
| 493 __ j(not_equal, miss, not_taken); | 489 __ mov(edx, FieldOperand(edx, Map::kBitField2Offset)); |
| 494 | 490 __ test(edx, Immediate(1 << Map::kNeedsLoading)); |
| 495 // Check that the function has been loaded. | 491 __ j(not_zero, miss, not_taken); |
| 496 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | |
| 497 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kLazyLoadDataOffset)); | |
| 498 __ cmp(edx, Factory::undefined_value()); | |
| 499 __ j(not_equal, miss, not_taken); | |
| 500 | 492 |
| 501 // Patch the receiver with the global proxy if necessary. | 493 // Patch the receiver with the global proxy if necessary. |
| 502 if (is_global_object) { | 494 if (is_global_object) { |
| 503 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 495 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
| 504 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 496 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
| 505 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 497 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
| 506 } | 498 } |
| 507 | 499 |
| 508 // Invoke the function. | 500 // Invoke the function. |
| 509 ParameterCount actual(argc); | 501 ParameterCount actual(argc); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 676 __ j(equal, &global, not_taken); | 668 __ j(equal, &global, not_taken); |
| 677 | 669 |
| 678 // Check for non-global object that requires access check. | 670 // Check for non-global object that requires access check. |
| 679 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); | 671 __ movzx_b(ebx, FieldOperand(ebx, Map::kBitFieldOffset)); |
| 680 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); | 672 __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); |
| 681 __ j(not_zero, &miss, not_taken); | 673 __ j(not_zero, &miss, not_taken); |
| 682 | 674 |
| 683 // Search the dictionary placing the result in eax. | 675 // Search the dictionary placing the result in eax. |
| 684 __ bind(&probe); | 676 __ bind(&probe); |
| 685 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx); | 677 GenerateDictionaryLoad(masm, &miss, edx, eax, ebx, ecx); |
| 686 GenerateCheckNonFunctionOrLoaded(masm, &miss, eax, edx); | 678 GenerateCheckNonObjectOrLoaded(masm, &miss, eax, edx); |
| 687 __ ret(0); | 679 __ ret(0); |
| 688 | 680 |
| 689 // Global object access: Check access rights. | 681 // Global object access: Check access rights. |
| 690 __ bind(&global); | 682 __ bind(&global); |
| 691 __ CheckAccessGlobalProxy(eax, edx, &miss); | 683 __ CheckAccessGlobalProxy(eax, edx, &miss); |
| 692 __ jmp(&probe); | 684 __ jmp(&probe); |
| 693 | 685 |
| 694 // Cache miss: Restore receiver from stack and jump to runtime. | 686 // Cache miss: Restore receiver from stack and jump to runtime. |
| 695 __ bind(&miss); | 687 __ bind(&miss); |
| 696 __ mov(eax, Operand(esp, 1 * kPointerSize)); | 688 __ mov(eax, Operand(esp, 1 * kPointerSize)); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 | 893 |
| 902 // Do tail-call to runtime routine. | 894 // Do tail-call to runtime routine. |
| 903 __ TailCallRuntime( | 895 __ TailCallRuntime( |
| 904 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); | 896 ExternalReference(IC_Utility(kSharedStoreIC_ExtendStorage)), 3); |
| 905 } | 897 } |
| 906 | 898 |
| 907 #undef __ | 899 #undef __ |
| 908 | 900 |
| 909 | 901 |
| 910 } } // namespace v8::internal | 902 } } // namespace v8::internal |
| OLD | NEW |