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

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

Issue 21067002: Simplify allocation stub for closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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
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 1005 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 // ESP + 4 : type arguments of instantiator (only if class is parameterized). 1016 // ESP + 4 : type arguments of instantiator (only if class is parameterized).
1017 // ESP : points to return address. 1017 // ESP : points to return address.
1018 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers. 1018 // Uses EAX, EBX, ECX, EDX, EDI as temporary registers.
1019 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 1019 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
1020 const Class& cls) { 1020 const Class& cls) {
1021 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; 1021 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
1022 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize; 1022 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
1023 const Immediate& raw_null = 1023 const Immediate& raw_null =
1024 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1024 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1025 // The generated code is different if the class is parameterized. 1025 // The generated code is different if the class is parameterized.
1026 const bool is_cls_parameterized = 1026 const bool is_cls_parameterized = cls.HasTypeArguments();
1027 cls.type_arguments_field_offset() != Class::kNoTypeArguments; 1027 ASSERT(!cls.HasTypeArguments() ||
1028 cls.type_arguments_field_offset() != Class::kNoTypeArguments);
srdjan 2013/07/29 16:23:15 ditto
1028 // kInlineInstanceSize is a constant used as a threshold for determining 1029 // kInlineInstanceSize is a constant used as a threshold for determining
1029 // when the object initialization should be done as a loop or as 1030 // when the object initialization should be done as a loop or as
1030 // straight line code. 1031 // straight line code.
1031 const int kInlineInstanceSize = 12; 1032 const int kInlineInstanceSize = 12;
1032 const intptr_t instance_size = cls.instance_size(); 1033 const intptr_t instance_size = cls.instance_size();
1033 ASSERT(instance_size > 0); 1034 ASSERT(instance_size > 0);
1034 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize(); 1035 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize();
1035 if (FLAG_inline_alloc && 1036 if (FLAG_inline_alloc &&
1036 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) { 1037 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) {
1037 Label slow_case; 1038 Label slow_case;
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 // Input parameters: 1189 // Input parameters:
1189 // ESP + 8 : receiver (null if not an implicit instance closure). 1190 // ESP + 8 : receiver (null if not an implicit instance closure).
1190 // ESP + 4 : type arguments object (null if class is no parameterized). 1191 // ESP + 4 : type arguments object (null if class is no parameterized).
1191 // ESP : points to return address. 1192 // ESP : points to return address.
1192 // Uses EAX, EBX, ECX, EDX as temporary registers. 1193 // Uses EAX, EBX, ECX, EDX as temporary registers.
1193 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1194 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1194 const Function& func) { 1195 const Function& func) {
1195 const Immediate& raw_null = 1196 const Immediate& raw_null =
1196 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1197 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1197 ASSERT(func.IsClosureFunction()); 1198 ASSERT(func.IsClosureFunction());
1198 const bool is_implicit_static_closure = 1199 ASSERT(!func.IsImplicitStaticClosureFunction());
1199 func.IsImplicitStaticClosureFunction();
1200 const bool is_implicit_instance_closure = 1200 const bool is_implicit_instance_closure =
1201 func.IsImplicitInstanceClosureFunction(); 1201 func.IsImplicitInstanceClosureFunction();
1202 const Class& cls = Class::ZoneHandle(func.signature_class()); 1202 const Class& cls = Class::ZoneHandle(func.signature_class());
1203 const bool has_type_arguments = cls.HasTypeArguments(); 1203 const bool has_type_arguments = cls.HasTypeArguments();
1204 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 1204 const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
1205 const intptr_t kReceiverOffset = 2 * kWordSize; 1205 const intptr_t kReceiverOffset = 2 * kWordSize;
1206 const intptr_t closure_size = Closure::InstanceSize(); 1206 const intptr_t closure_size = Closure::InstanceSize();
1207 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1207 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1208 if (FLAG_inline_alloc && 1208 if (FLAG_inline_alloc &&
1209 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { 1209 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
(...skipping 29 matching lines...) Expand all
1239 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); 1239 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags));
1240 1240
1241 // Initialize the function field in the object. 1241 // Initialize the function field in the object.
1242 // EAX: new closure object. 1242 // EAX: new closure object.
1243 // ECX: new context object (only if is_implicit_closure). 1243 // ECX: new context object (only if is_implicit_closure).
1244 // EBX: next object start. 1244 // EBX: next object start.
1245 __ LoadObject(EDX, func); // Load function of closure to be allocated. 1245 __ LoadObject(EDX, func); // Load function of closure to be allocated.
1246 __ movl(Address(EAX, Closure::function_offset()), EDX); 1246 __ movl(Address(EAX, Closure::function_offset()), EDX);
1247 1247
1248 // Setup the context for this closure. 1248 // Setup the context for this closure.
1249 if (is_implicit_static_closure) { 1249 if (is_implicit_instance_closure) {
1250 ObjectStore* object_store = Isolate::Current()->object_store();
1251 ASSERT(object_store != NULL);
1252 const Context& empty_context =
1253 Context::ZoneHandle(object_store->empty_context());
1254 __ LoadObject(EDX, empty_context);
1255 __ movl(Address(EAX, Closure::context_offset()), EDX);
1256 } else if (is_implicit_instance_closure) {
1257 // Initialize the new context capturing the receiver. 1250 // Initialize the new context capturing the receiver.
1258 const Class& context_class = Class::ZoneHandle(Object::context_class()); 1251 const Class& context_class = Class::ZoneHandle(Object::context_class());
1259 // Set the tags. 1252 // Set the tags.
1260 uword tags = 0; 1253 uword tags = 0;
1261 tags = RawObject::SizeTag::update(context_size, tags); 1254 tags = RawObject::SizeTag::update(context_size, tags);
1262 tags = RawObject::ClassIdTag::update(context_class.id(), tags); 1255 tags = RawObject::ClassIdTag::update(context_class.id(), tags);
1263 __ movl(Address(ECX, Context::tags_offset()), Immediate(tags)); 1256 __ movl(Address(ECX, Context::tags_offset()), Immediate(tags));
1264 1257
1265 // Set number of variables field to 1 (for captured receiver). 1258 // Set number of variables field to 1 (for captured receiver).
1266 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); 1259 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); 1291 __ movl(ECX, Address(ESP, kTypeArgumentsOffset));
1299 } 1292 }
1300 if (is_implicit_instance_closure) { 1293 if (is_implicit_instance_closure) {
1301 __ movl(EAX, Address(ESP, kReceiverOffset)); 1294 __ movl(EAX, Address(ESP, kReceiverOffset));
1302 } 1295 }
1303 // Create a stub frame as we are pushing some objects on the stack before 1296 // Create a stub frame as we are pushing some objects on the stack before
1304 // calling into the runtime. 1297 // calling into the runtime.
1305 __ EnterStubFrame(); 1298 __ EnterStubFrame();
1306 __ pushl(raw_null); // Setup space on stack for return value. 1299 __ pushl(raw_null); // Setup space on stack for return value.
1307 __ PushObject(func); 1300 __ PushObject(func);
1308 if (is_implicit_static_closure) { 1301 if (is_implicit_instance_closure) {
1309 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); 1302 __ pushl(EAX); // Receiver.
1303 }
1304 if (has_type_arguments) {
1305 __ pushl(ECX); // Push type arguments of closure to be allocated.
1310 } else { 1306 } else {
1311 if (is_implicit_instance_closure) { 1307 __ pushl(raw_null); // Push null type arguments.
1312 __ pushl(EAX); // Receiver. 1308 }
1313 } 1309 if (is_implicit_instance_closure) {
1314 if (has_type_arguments) { 1310 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
1315 __ pushl(ECX); // Push type arguments of closure to be allocated. 1311 __ popl(EAX); // Pop argument (type arguments of object).
1316 } else { 1312 __ popl(EAX); // Pop receiver.
1317 __ pushl(raw_null); // Push null type arguments. 1313 } else {
1318 } 1314 ASSERT(func.IsNonImplicitClosureFunction());
1319 if (is_implicit_instance_closure) { 1315 __ CallRuntime(kAllocateClosureRuntimeEntry);
1320 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); 1316 __ popl(EAX); // Pop argument (type arguments of object).
1321 __ popl(EAX); // Pop argument (type arguments of object).
1322 __ popl(EAX); // Pop receiver.
1323 } else {
1324 ASSERT(func.IsNonImplicitClosureFunction());
1325 __ CallRuntime(kAllocateClosureRuntimeEntry);
1326 __ popl(EAX); // Pop argument (type arguments of object).
1327 }
1328 } 1317 }
1329 __ popl(EAX); // Pop function object. 1318 __ popl(EAX); // Pop function object.
1330 __ popl(EAX); 1319 __ popl(EAX);
1331 // EAX: new object 1320 // EAX: new object
1332 // Restore the frame pointer. 1321 // Restore the frame pointer.
1333 __ LeaveFrame(); 1322 __ LeaveFrame();
1334 __ ret(); 1323 __ ret();
1335 } 1324 }
1336 1325
1337 1326
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2200 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2212 __ popl(temp); 2201 __ popl(temp);
2213 __ popl(right); 2202 __ popl(right);
2214 __ popl(left); 2203 __ popl(left);
2215 __ ret(); 2204 __ ret();
2216 } 2205 }
2217 2206
2218 } // namespace dart 2207 } // namespace dart
2219 2208
2220 #endif // defined TARGET_ARCH_IA32 2209 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698