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

Side by Side Diff: runtime/vm/stub_code_x64.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
« runtime/vm/stub_code_ia32.cc ('K') | « runtime/vm/stub_code_mips.cc ('k') | no next file » | 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_X64) 6 #if defined(TARGET_ARCH_X64)
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 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 // RSP + 16 : type arguments object (only if class is parameterized). 998 // RSP + 16 : type arguments object (only if class is parameterized).
999 // RSP + 8 : type arguments of instantiator (only if class is parameterized). 999 // RSP + 8 : type arguments of instantiator (only if class is parameterized).
1000 // RSP : points to return address. 1000 // RSP : points to return address.
1001 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 1001 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
1002 const Class& cls) { 1002 const Class& cls) {
1003 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize; 1003 const intptr_t kObjectTypeArgumentsOffset = 2 * kWordSize;
1004 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize; 1004 const intptr_t kInstantiatorTypeArgumentsOffset = 1 * kWordSize;
1005 const Immediate& raw_null = 1005 const Immediate& raw_null =
1006 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1006 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1007 // The generated code is different if the class is parameterized. 1007 // The generated code is different if the class is parameterized.
1008 const bool is_cls_parameterized = 1008 const bool is_cls_parameterized = cls.HasTypeArguments();
1009 cls.type_arguments_field_offset() != Class::kNoTypeArguments; 1009 ASSERT(!cls.HasTypeArguments() ||
1010 cls.type_arguments_field_offset() != Class::kNoTypeArguments);
1010 // kInlineInstanceSize is a constant used as a threshold for determining 1011 // kInlineInstanceSize is a constant used as a threshold for determining
1011 // when the object initialization should be done as a loop or as 1012 // when the object initialization should be done as a loop or as
1012 // straight line code. 1013 // straight line code.
1013 const int kInlineInstanceSize = 12; // In words. 1014 const int kInlineInstanceSize = 12; // In words.
1014 const intptr_t instance_size = cls.instance_size(); 1015 const intptr_t instance_size = cls.instance_size();
1015 ASSERT(instance_size > 0); 1016 ASSERT(instance_size > 0);
1016 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize(); 1017 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize();
1017 if (FLAG_inline_alloc && 1018 if (FLAG_inline_alloc &&
1018 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) { 1019 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) {
1019 Label slow_case; 1020 Label slow_case;
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 // Called for inline allocation of closures. 1172 // Called for inline allocation of closures.
1172 // Input parameters: 1173 // Input parameters:
1173 // RSP + 16 : receiver (null if not an implicit instance closure). 1174 // RSP + 16 : receiver (null if not an implicit instance closure).
1174 // RSP + 8 : type arguments object (null if class is not parameterized). 1175 // RSP + 8 : type arguments object (null if class is not parameterized).
1175 // RSP : points to return address. 1176 // RSP : points to return address.
1176 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1177 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1177 const Function& func) { 1178 const Function& func) {
1178 const Immediate& raw_null = 1179 const Immediate& raw_null =
1179 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1180 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1180 ASSERT(func.IsClosureFunction()); 1181 ASSERT(func.IsClosureFunction());
1181 const bool is_implicit_static_closure = 1182 ASSERT(!func.IsImplicitStaticClosureFunction());
1182 func.IsImplicitStaticClosureFunction();
1183 const bool is_implicit_instance_closure = 1183 const bool is_implicit_instance_closure =
1184 func.IsImplicitInstanceClosureFunction(); 1184 func.IsImplicitInstanceClosureFunction();
1185 const Class& cls = Class::ZoneHandle(func.signature_class()); 1185 const Class& cls = Class::ZoneHandle(func.signature_class());
1186 const bool has_type_arguments = cls.HasTypeArguments(); 1186 const bool has_type_arguments = cls.HasTypeArguments();
1187 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; 1187 const intptr_t kTypeArgumentsOffset = 1 * kWordSize;
1188 const intptr_t kReceiverOffset = 2 * kWordSize; 1188 const intptr_t kReceiverOffset = 2 * kWordSize;
1189 const intptr_t closure_size = Closure::InstanceSize(); 1189 const intptr_t closure_size = Closure::InstanceSize();
1190 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1190 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1191 if (FLAG_inline_alloc && 1191 if (FLAG_inline_alloc &&
1192 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { 1192 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags)); 1225 __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags));
1226 1226
1227 // Initialize the function field in the object. 1227 // Initialize the function field in the object.
1228 // RAX: new closure object. 1228 // RAX: new closure object.
1229 // RBX: new context object (only if is_implicit_closure). 1229 // RBX: new context object (only if is_implicit_closure).
1230 // R13: next object start. 1230 // R13: next object start.
1231 __ LoadObject(R10, func); // Load function of closure to be allocated. 1231 __ LoadObject(R10, func); // Load function of closure to be allocated.
1232 __ movq(Address(RAX, Closure::function_offset()), R10); 1232 __ movq(Address(RAX, Closure::function_offset()), R10);
1233 1233
1234 // Setup the context for this closure. 1234 // Setup the context for this closure.
1235 if (is_implicit_static_closure) { 1235 if (is_implicit_instance_closure) {
1236 ObjectStore* object_store = Isolate::Current()->object_store();
1237 ASSERT(object_store != NULL);
1238 const Context& empty_context =
1239 Context::ZoneHandle(object_store->empty_context());
1240 __ LoadObject(R10, empty_context);
1241 __ movq(Address(RAX, Closure::context_offset()), R10);
1242 } else if (is_implicit_instance_closure) {
1243 // Initialize the new context capturing the receiver. 1236 // Initialize the new context capturing the receiver.
1244 1237
1245 const Class& context_class = Class::ZoneHandle(Object::context_class()); 1238 const Class& context_class = Class::ZoneHandle(Object::context_class());
1246 // Set the tags. 1239 // Set the tags.
1247 uword tags = 0; 1240 uword tags = 0;
1248 tags = RawObject::SizeTag::update(context_size, tags); 1241 tags = RawObject::SizeTag::update(context_size, tags);
1249 tags = RawObject::ClassIdTag::update(context_class.id(), tags); 1242 tags = RawObject::ClassIdTag::update(context_class.id(), tags);
1250 __ movq(Address(RBX, Context::tags_offset()), Immediate(tags)); 1243 __ movq(Address(RBX, Context::tags_offset()), Immediate(tags));
1251 1244
1252 // Set number of variables field to 1 (for captured receiver). 1245 // Set number of variables field to 1 (for captured receiver).
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 if (has_type_arguments) { 1277 if (has_type_arguments) {
1285 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); 1278 __ movq(RCX, Address(RSP, kTypeArgumentsOffset));
1286 } 1279 }
1287 if (is_implicit_instance_closure) { 1280 if (is_implicit_instance_closure) {
1288 __ movq(RAX, Address(RSP, kReceiverOffset)); 1281 __ movq(RAX, Address(RSP, kReceiverOffset));
1289 } 1282 }
1290 // Create the stub frame. 1283 // Create the stub frame.
1291 __ EnterStubFrame(); 1284 __ EnterStubFrame();
1292 __ pushq(raw_null); // Setup space on stack for the return value. 1285 __ pushq(raw_null); // Setup space on stack for the return value.
1293 __ PushObject(func); 1286 __ PushObject(func);
1294 if (is_implicit_static_closure) { 1287 if (is_implicit_instance_closure) {
1295 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); 1288 __ pushq(RAX); // Receiver.
1289 }
1290 if (has_type_arguments) {
1291 __ pushq(RCX); // Push type arguments of closure to be allocated.
1296 } else { 1292 } else {
1297 if (is_implicit_instance_closure) { 1293 __ pushq(raw_null); // Push null type arguments.
1298 __ pushq(RAX); // Receiver. 1294 }
1299 } 1295 if (is_implicit_instance_closure) {
1300 if (has_type_arguments) { 1296 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
1301 __ pushq(RCX); // Push type arguments of closure to be allocated. 1297 __ popq(RAX); // Pop type arguments.
1302 } else { 1298 __ popq(RAX); // Pop receiver.
1303 __ pushq(raw_null); // Push null type arguments. 1299 } else {
1304 } 1300 ASSERT(func.IsNonImplicitClosureFunction());
1305 if (is_implicit_instance_closure) { 1301 __ CallRuntime(kAllocateClosureRuntimeEntry);
1306 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry); 1302 __ popq(RAX); // Pop type arguments.
1307 __ popq(RAX); // Pop type arguments.
1308 __ popq(RAX); // Pop receiver.
1309 } else {
1310 ASSERT(func.IsNonImplicitClosureFunction());
1311 __ CallRuntime(kAllocateClosureRuntimeEntry);
1312 __ popq(RAX); // Pop type arguments.
1313 }
1314 } 1303 }
1315 __ popq(RAX); // Pop the function object. 1304 __ popq(RAX); // Pop the function object.
1316 __ popq(RAX); // Pop the result. 1305 __ popq(RAX); // Pop the result.
1317 // RAX: New closure object. 1306 // RAX: New closure object.
1318 // Restore the calling frame. 1307 // Restore the calling frame.
1319 __ LeaveFrame(); 1308 __ LeaveFrame();
1320 __ ret(); 1309 __ ret();
1321 } 1310 }
1322 1311
1323 1312
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 __ movq(right, Address(RSP, 3 * kWordSize)); 2158 __ movq(right, Address(RSP, 3 * kWordSize));
2170 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2159 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2171 __ popq(right); 2160 __ popq(right);
2172 __ popq(left); 2161 __ popq(left);
2173 __ ret(); 2162 __ ret();
2174 } 2163 }
2175 2164
2176 } // namespace dart 2165 } // namespace dart
2177 2166
2178 #endif // defined TARGET_ARCH_X64 2167 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/stub_code_ia32.cc ('K') | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698