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

Side by Side Diff: runtime/vm/stub_code_ia32.cc

Issue 10458031: In generated code for x64 don't load object's class directly from class_ field. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Eliminate CoreClass helpers on ia32/x64 and use class ids for array classes. Created 8 years, 6 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 | « runtime/vm/opt_code_generator_ia32.cc ('k') | runtime/vm/stub_code_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 (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_IA32) 6 #if defined(TARGET_ARCH_IA32)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/code_generator.h" 10 #include "vm/code_generator.h"
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // Total number of args is the first Smi in args descriptor array (EDX). 288 // Total number of args is the first Smi in args descriptor array (EDX).
289 __ movl(EAX, FieldAddress(EDX, Array::data_offset())); 289 __ movl(EAX, FieldAddress(EDX, Array::data_offset()));
290 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // Get receiver. EAX is a Smi. 290 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // Get receiver. EAX is a Smi.
291 // TODO(srdjan): Remove the special casing below for null receiver, once 291 // TODO(srdjan): Remove the special casing below for null receiver, once
292 // NullClass is implemented. 292 // NullClass is implemented.
293 __ cmpl(EAX, raw_null); 293 __ cmpl(EAX, raw_null);
294 // Use Object class if receiver is null. 294 // Use Object class if receiver is null.
295 __ j(EQUAL, &null_receiver, Assembler::kNearJump); 295 __ j(EQUAL, &null_receiver, Assembler::kNearJump);
296 __ testl(EAX, Immediate(kSmiTagMask)); 296 __ testl(EAX, Immediate(kSmiTagMask));
297 __ j(ZERO, &smi_receiver, Assembler::kNearJump); 297 __ j(ZERO, &smi_receiver, Assembler::kNearJump);
298 __ LoadClassOfObject(EAX, EAX, EDI); 298 __ LoadClass(EAX, EAX, EDI);
299 __ jmp(&class_in_eax, Assembler::kNearJump); 299 __ jmp(&class_in_eax, Assembler::kNearJump);
300 __ Bind(&smi_receiver); 300 __ Bind(&smi_receiver);
301 // For Smis we need to get the class from the isolate. 301 // For Smis we need to get the class from the isolate.
302 // Load current Isolate pointer from Context structure into EAX. 302 // Load current Isolate pointer from Context structure into EAX.
303 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 303 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
304 __ movl(EAX, Address(EAX, Isolate::object_store_offset())); 304 __ movl(EAX, Address(EAX, Isolate::object_store_offset()));
305 __ movl(EAX, Address(EAX, ObjectStore::smi_class_offset())); 305 __ movl(EAX, Address(EAX, ObjectStore::smi_class_offset()));
306 __ jmp(&class_in_eax, Assembler::kNearJump); 306 __ jmp(&class_in_eax, Assembler::kNearJump);
307 __ Bind(&null_receiver); 307 __ Bind(&null_receiver);
308 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); 308 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset()));
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 765
766 // Verify that EDI is a closure by checking its class. 766 // Verify that EDI is a closure by checking its class.
767 Label not_closure; 767 Label not_closure;
768 __ cmpl(EDI, raw_null); 768 __ cmpl(EDI, raw_null);
769 // Not a closure, but null object. 769 // Not a closure, but null object.
770 __ j(EQUAL, &not_closure, Assembler::kNearJump); 770 __ j(EQUAL, &not_closure, Assembler::kNearJump);
771 __ testl(EDI, Immediate(kSmiTagMask)); 771 __ testl(EDI, Immediate(kSmiTagMask));
772 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi. 772 __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi.
773 // Verify that the class of the object is a closure class by checking that 773 // Verify that the class of the object is a closure class by checking that
774 // class.signature_function() is not null. 774 // class.signature_function() is not null.
775 __ LoadClassOfObject(EAX, EDI, ECX); 775 __ LoadClass(EAX, EDI, ECX);
776 __ movl(EAX, FieldAddress(EAX, Class::signature_function_offset())); 776 __ movl(EAX, FieldAddress(EAX, Class::signature_function_offset()));
777 __ cmpl(EAX, raw_null); 777 __ cmpl(EAX, raw_null);
778 // Actual class is not a closure class. 778 // Actual class is not a closure class.
779 __ j(EQUAL, &not_closure, Assembler::kNearJump); 779 __ j(EQUAL, &not_closure, Assembler::kNearJump);
780 780
781 // EAX is just the signature function. Load the actual closure function. 781 // EAX is just the signature function. Load the actual closure function.
782 __ movl(ECX, FieldAddress(EDI, Closure::function_offset())); 782 __ movl(ECX, FieldAddress(EDI, Closure::function_offset()));
783 783
784 // Load closure context in CTX; note that CTX has already been preserved. 784 // Load closure context in CTX; note that CTX has already been preserved.
785 __ movl(CTX, FieldAddress(EDI, Closure::context_offset())); 785 __ movl(CTX, FieldAddress(EDI, Closure::context_offset()));
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after
1584 // 'num_args_tested' is stored as an untagged int. 1584 // 'num_args_tested' is stored as an untagged int.
1585 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); 1585 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset()));
1586 __ cmpl(EBX, Immediate(num_args)); 1586 __ cmpl(EBX, Immediate(num_args));
1587 __ j(EQUAL, &ok, Assembler::kNearJump); 1587 __ j(EQUAL, &ok, Assembler::kNearJump);
1588 __ Stop("Incorrect stub for IC data"); 1588 __ Stop("Incorrect stub for IC data");
1589 __ Bind(&ok); 1589 __ Bind(&ok);
1590 } 1590 }
1591 #endif // DEBUG 1591 #endif // DEBUG
1592 1592
1593 // Loop that checks if there is an IC data match. 1593 // Loop that checks if there is an IC data match.
1594 // EAX: receiver's class.
1595 // ECX: IC data object (preserved). 1594 // ECX: IC data object (preserved).
1596 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1595 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1597 // EBX: ic_data_array with check entries: classes and target functions. 1596 // EBX: ic_data_array with check entries: classes and target functions.
1598 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1597 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1599 // EBX: points directly to the first ic data array element. 1598 // EBX: points directly to the first ic data array element.
1600 Label loop, found; 1599 Label loop, found;
1601 if (num_args == 1) { 1600 if (num_args == 1) {
1602 __ call(&get_class); 1601 __ call(&get_class);
1603 // EAX: receiver's class 1602 // EAX: receiver's class
1604 __ Bind(&loop); 1603 __ Bind(&loop);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1690 Label not_smi; 1689 Label not_smi;
1691 // Test if Smi -> load Smi class for comparison. 1690 // Test if Smi -> load Smi class for comparison.
1692 __ testl(EAX, Immediate(kSmiTagMask)); 1691 __ testl(EAX, Immediate(kSmiTagMask));
1693 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump); 1692 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1694 const Class& smi_class = 1693 const Class& smi_class =
1695 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class()); 1694 Class::ZoneHandle(Isolate::Current()->object_store()->smi_class());
1696 __ LoadObject(EAX, smi_class); 1695 __ LoadObject(EAX, smi_class);
1697 __ ret(); 1696 __ ret();
1698 1697
1699 __ Bind(&not_smi); 1698 __ Bind(&not_smi);
1700 __ LoadClassOfObject(EAX, EAX, EDI); 1699 __ LoadClass(EAX, EAX, EDI);
1701 __ ret(); 1700 __ ret();
1702 } 1701 }
1703 1702
1704 1703
1705 // Use inline cache data array to invoke the target or continue in inline 1704 // Use inline cache data array to invoke the target or continue in inline
1706 // cache miss handler. Stub for 1-argument check (receiver class). 1705 // cache miss handler. Stub for 1-argument check (receiver class).
1707 // ECX: Inline cache data array 1706 // ECX: Inline cache data array
1708 // EDX: Arguments array 1707 // EDX: Arguments array
1709 // TOS(0): return address 1708 // TOS(0): return address
1710 // Inline cache data array structure: 1709 // Inline cache data array structure:
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 // TOS + 3: SubtypeTestCache. 1795 // TOS + 3: SubtypeTestCache.
1797 // Result in ECX: null -> not found, otherwise result (true or false). 1796 // Result in ECX: null -> not found, otherwise result (true or false).
1798 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { 1797 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
1799 ASSERT((1 <= n) && (n <= 3)); 1798 ASSERT((1 <= n) && (n <= 3));
1800 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize; 1799 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize;
1801 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize; 1800 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize;
1802 const intptr_t kCacheOffsetInBytes = 3 * kWordSize; 1801 const intptr_t kCacheOffsetInBytes = 3 * kWordSize;
1803 const Immediate raw_null = 1802 const Immediate raw_null =
1804 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1803 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1805 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes)); 1804 __ movl(EAX, Address(ESP, kInstanceOffsetInBytes));
1806 __ LoadClassOfObject(ECX, EAX, EBX); 1805 __ LoadClass(ECX, EAX, EBX);
1807 // EAX: instance, ECX: instance-class. 1806 // EAX: instance, ECX: instance-class.
1808 // Get instance type arguments 1807 // Get instance type arguments
1809 if (n > 1) { 1808 if (n > 1) {
1810 // Compute instance type arguments into EBX. 1809 // Compute instance type arguments into EBX.
1811 Label has_no_type_arguments; 1810 Label has_no_type_arguments;
1812 __ movl(EBX, raw_null); 1811 __ movl(EBX, raw_null);
1813 __ movl(EDI, FieldAddress(ECX, 1812 __ movl(EDI, FieldAddress(ECX,
1814 Class::type_arguments_instance_field_offset_offset())); 1813 Class::type_arguments_instance_field_offset_offset()));
1815 __ cmpl(EDI, Immediate(Class::kNoTypeArguments)); 1814 __ cmpl(EDI, Immediate(Class::kNoTypeArguments));
1816 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump); 1815 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 // TOS + 2: instance. 1891 // TOS + 2: instance.
1893 // TOS + 3: cache array. 1892 // TOS + 3: cache array.
1894 // Result in ECX: null -> not found, otherwise result (true or false). 1893 // Result in ECX: null -> not found, otherwise result (true or false).
1895 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) { 1894 void StubCode::GenerateSubtype3TestCacheStub(Assembler* assembler) {
1896 GenerateSubtypeNTestCacheStub(assembler, 3); 1895 GenerateSubtypeNTestCacheStub(assembler, 3);
1897 } 1896 }
1898 1897
1899 } // namespace dart 1898 } // namespace dart
1900 1899
1901 #endif // defined TARGET_ARCH_IA32 1900 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/opt_code_generator_ia32.cc ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698