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

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

Issue 163683006: Simplify generated code for object allocation with type arguments. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 6 years, 10 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/stub_code_arm.cc ('k') | runtime/vm/stub_code_mips.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument. 1095 __ movl(Address(ESP, 0), EAX); // Push the isolate as the only argument.
1096 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); 1096 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
1097 // Restore callee-saved registers, tear down frame. 1097 // Restore callee-saved registers, tear down frame.
1098 __ LeaveCallRuntimeFrame(); 1098 __ LeaveCallRuntimeFrame();
1099 __ ret(); 1099 __ ret();
1100 } 1100 }
1101 1101
1102 1102
1103 // Called for inline allocation of objects. 1103 // Called for inline allocation of objects.
1104 // Input parameters: 1104 // Input parameters:
1105 // ESP + 8 : type arguments object (only if class is parameterized). 1105 // ESP + 4 : type arguments object (only if class is parameterized).
1106 // ESP + 4 : type arguments of instantiator (only if class is parameterized).
1107 // ESP : points to return address. 1106 // ESP : points to return address.
1108 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers. 1107 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers.
1109 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 1108 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
1110 const Class& cls) { 1109 const Class& cls) {
1111 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; 1110 const intptr_t kObjectTypeArgumentsOffset = 1 * kWordSize;
1112 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
1113 const Immediate& raw_null = 1111 const Immediate& raw_null =
1114 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1112 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1115 // The generated code is different if the class is parameterized. 1113 // The generated code is different if the class is parameterized.
1116 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; 1114 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
1117 ASSERT(!is_cls_parameterized || 1115 ASSERT(!is_cls_parameterized ||
1118 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1116 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1119 // kInlineInstanceSize is a constant used as a threshold for determining 1117 // kInlineInstanceSize is a constant used as a threshold for determining
1120 // when the object initialization should be done as a loop or as 1118 // when the object initialization should be done as a loop or as
1121 // straight line code. 1119 // straight line code.
1122 const int kInlineInstanceSize = 12; // In words. 1120 const int kInlineInstanceSize = 12; // In words.
1123 const intptr_t instance_size = cls.instance_size(); 1121 const intptr_t instance_size = cls.instance_size();
1124 ASSERT(instance_size > 0); 1122 ASSERT(instance_size > 0);
1125 Label slow_case_with_type_arguments; 1123 Label slow_case_with_type_arguments;
1126 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { 1124 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
1127 Label slow_case_reload_type_arguments; 1125 Label slow_case_reload_type_arguments;
1128 if (is_cls_parameterized) { 1126 if (is_cls_parameterized) {
1129 // Instantiation of the type arguments vector is only required if an
1130 // instantiator is provided (not kNoInstantiator, but may be null).
1131 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); 1127 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
1132 __ movl(EDI, Address(ESP, kInstantiatorTypeArgumentsOffset));
1133 Label type_arguments_ready;
1134 __ cmpl(EDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1135 __ j(EQUAL, &type_arguments_ready, Assembler::kNearJump);
1136 // Lookup instantiator EDI in instantiations array of type arguments EDX
1137 // and, if found, use cached instantiated type arguments.
1138 __ movl(EAX, FieldAddress(EDX, TypeArguments::instantiations_offset()));
1139 __ movl(EBX, FieldAddress(EAX, Array::length_offset()));
1140 __ leal(EAX, FieldAddress(EAX, Array::data_offset()));
1141 __ leal(EBX, Address(EAX, EBX, TIMES_2, 0)); // EBX is smi.
1142 Label loop, found;
1143 __ Bind(&loop);
1144 __ cmpl(EAX, EBX);
1145 __ j(ABOVE_EQUAL, &slow_case_reload_type_arguments);
1146 __ movl(EDX, Address(EAX, 0 * kWordSize)); // Cached instantiator.
1147 __ cmpl(EDX, EDI);
1148 __ j(EQUAL, &found, Assembler::kNearJump);
1149 __ cmpl(EDX, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1150 __ j(EQUAL, &slow_case_reload_type_arguments);
1151 __ addl(EAX, Immediate(2 * kWordSize));
1152 __ jmp(&loop, Assembler::kNearJump);
1153 __ Bind(&found);
1154 __ movl(EDX, Address(EAX, 1 * kWordSize)); // Cached instantiated args.
1155 __ movl(EDI, Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1156 __ Bind(&type_arguments_ready);
1157 // EDX: instantiated type arguments. 1128 // EDX: instantiated type arguments.
1158 // EDI: kNoInstantiator.
1159 } 1129 }
1160 // Allocate the object and update top to point to 1130 // Allocate the object and update top to point to
1161 // next object start and initialize the allocated object. 1131 // next object start and initialize the allocated object.
1162 // EDX: instantiated type arguments (if is_cls_parameterized). 1132 // EDX: instantiated type arguments (if is_cls_parameterized).
1163 // EDI: kNoInstantiator (if is_cls_parameterized).
1164 Heap* heap = Isolate::Current()->heap(); 1133 Heap* heap = Isolate::Current()->heap();
1165 __ movl(EAX, Address::Absolute(heap->TopAddress())); 1134 __ movl(EAX, Address::Absolute(heap->TopAddress()));
1166 __ leal(EBX, Address(EAX, instance_size)); 1135 __ leal(EBX, Address(EAX, instance_size));
1167 // Check if the allocation fits into the remaining space. 1136 // Check if the allocation fits into the remaining space.
1168 // EAX: potential new object start. 1137 // EAX: potential new object start.
1169 // EBX: potential next object start. 1138 // EBX: potential next object start.
1170 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); 1139 __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
1171 if (FLAG_use_slow_path) { 1140 if (FLAG_use_slow_path) {
1172 __ jmp(&slow_case_with_type_arguments); 1141 __ jmp(&slow_case_with_type_arguments);
1173 } else { 1142 } else {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 } 1195 }
1227 // Done allocating and initializing the instance. 1196 // Done allocating and initializing the instance.
1228 // EAX: new object. 1197 // EAX: new object.
1229 __ addl(EAX, Immediate(kHeapObjectTag)); 1198 __ addl(EAX, Immediate(kHeapObjectTag));
1230 __ ret(); 1199 __ ret();
1231 1200
1232 __ Bind(&slow_case_reload_type_arguments); 1201 __ Bind(&slow_case_reload_type_arguments);
1233 } 1202 }
1234 if (is_cls_parameterized) { 1203 if (is_cls_parameterized) {
1235 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); 1204 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
1236 __ movl(EDI, Address(ESP, kInstantiatorTypeArgumentsOffset));
1237 } 1205 }
1238 __ Bind(&slow_case_with_type_arguments); 1206 __ Bind(&slow_case_with_type_arguments);
1239 // If is_cls_parameterized: 1207 // If is_cls_parameterized:
1240 // EDX: new object type arguments (instantiated or not). 1208 // EDX: new object type arguments.
1241 // EDI: instantiator type arguments or kNoInstantiator.
1242 // Create a stub frame as we are pushing some objects on the stack before 1209 // Create a stub frame as we are pushing some objects on the stack before
1243 // calling into the runtime. 1210 // calling into the runtime.
1244 __ EnterStubFrame(); 1211 __ EnterStubFrame();
1245 __ pushl(raw_null); // Setup space on stack for return value. 1212 __ pushl(raw_null); // Setup space on stack for return value.
1246 __ PushObject(cls); // Push class of object to be allocated. 1213 __ PushObject(cls); // Push class of object to be allocated.
1247 if (is_cls_parameterized) { 1214 if (is_cls_parameterized) {
1248 __ pushl(EDX); // Push type arguments of object to be allocated. 1215 __ pushl(EDX); // Push type arguments of object to be allocated.
1249 __ pushl(EDI); // Push type arguments of instantiator.
1250 } else { 1216 } else {
1251 __ pushl(raw_null); // Push null type arguments. 1217 __ pushl(raw_null); // Push null type arguments.
1252 __ pushl(Immediate(Smi::RawValue(StubCode::kNoInstantiator)));
1253 } 1218 }
1254 __ CallRuntime(kAllocateObjectRuntimeEntry, 3); // Allocate object. 1219 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
1255 __ popl(EAX); // Pop argument (instantiator).
1256 __ popl(EAX); // Pop argument (type arguments of object). 1220 __ popl(EAX); // Pop argument (type arguments of object).
1257 __ popl(EAX); // Pop argument (class of object). 1221 __ popl(EAX); // Pop argument (class of object).
1258 __ popl(EAX); // Pop result (newly allocated object). 1222 __ popl(EAX); // Pop result (newly allocated object).
1259 // EAX: new object 1223 // EAX: new object
1260 // Restore the frame pointer. 1224 // Restore the frame pointer.
1261 __ LeaveFrame(); 1225 __ LeaveFrame();
1262 __ ret(); 1226 __ ret();
1263 } 1227 }
1264 1228
1265 1229
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 const Register temp = ECX; 2121 const Register temp = ECX;
2158 __ movl(left, Address(ESP, 2 * kWordSize)); 2122 __ movl(left, Address(ESP, 2 * kWordSize));
2159 __ movl(right, Address(ESP, 1 * kWordSize)); 2123 __ movl(right, Address(ESP, 1 * kWordSize));
2160 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2124 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2161 __ ret(); 2125 __ ret();
2162 } 2126 }
2163 2127
2164 } // namespace dart 2128 } // namespace dart
2165 2129
2166 #endif // defined TARGET_ARCH_IA32 2130 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698