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

Side by Side Diff: runtime/vm/stub_code_arm.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_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 969
970 970
971 // Called for inline allocation of objects. 971 // Called for inline allocation of objects.
972 // Input parameters: 972 // Input parameters:
973 // LR : return address. 973 // LR : return address.
974 // SP + 4 : type arguments object (only if class is parameterized). 974 // SP + 4 : type arguments object (only if class is parameterized).
975 // SP + 0 : type arguments of instantiator (only if class is parameterized). 975 // SP + 0 : type arguments of instantiator (only if class is parameterized).
976 void StubCode::GenerateAllocationStubForClass(Assembler* assembler, 976 void StubCode::GenerateAllocationStubForClass(Assembler* assembler,
977 const Class& cls) { 977 const Class& cls) {
978 // The generated code is different if the class is parameterized. 978 // The generated code is different if the class is parameterized.
979 const bool is_cls_parameterized = 979 const bool is_cls_parameterized = cls.HasTypeArguments();
980 cls.type_arguments_field_offset() != Class::kNoTypeArguments; 980 ASSERT(!cls.HasTypeArguments() ||
981 cls.type_arguments_field_offset() != Class::kNoTypeArguments);
srdjan 2013/07/29 16:23:15 Add parentheses
981 // kInlineInstanceSize is a constant used as a threshold for determining 982 // kInlineInstanceSize is a constant used as a threshold for determining
982 // when the object initialization should be done as a loop or as 983 // when the object initialization should be done as a loop or as
983 // straight line code. 984 // straight line code.
984 const int kInlineInstanceSize = 12; 985 const int kInlineInstanceSize = 12;
985 const intptr_t instance_size = cls.instance_size(); 986 const intptr_t instance_size = cls.instance_size();
986 ASSERT(instance_size > 0); 987 ASSERT(instance_size > 0);
987 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize(); 988 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize();
988 if (FLAG_inline_alloc && 989 if (FLAG_inline_alloc &&
989 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) { 990 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) {
990 Label slow_case; 991 Label slow_case;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1137
1137 1138
1138 // Called for inline allocation of closures. 1139 // Called for inline allocation of closures.
1139 // Input parameters: 1140 // Input parameters:
1140 // LR : return address. 1141 // LR : return address.
1141 // SP + 4 : receiver (null if not an implicit instance closure). 1142 // SP + 4 : receiver (null if not an implicit instance closure).
1142 // SP + 0 : type arguments object (null if class is no parameterized). 1143 // SP + 0 : type arguments object (null if class is no parameterized).
1143 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1144 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1144 const Function& func) { 1145 const Function& func) {
1145 ASSERT(func.IsClosureFunction()); 1146 ASSERT(func.IsClosureFunction());
1146 const bool is_implicit_static_closure = 1147 ASSERT(!func.IsImplicitStaticClosureFunction());
1147 func.IsImplicitStaticClosureFunction();
1148 const bool is_implicit_instance_closure = 1148 const bool is_implicit_instance_closure =
1149 func.IsImplicitInstanceClosureFunction(); 1149 func.IsImplicitInstanceClosureFunction();
1150 const Class& cls = Class::ZoneHandle(func.signature_class()); 1150 const Class& cls = Class::ZoneHandle(func.signature_class());
1151 const bool has_type_arguments = cls.HasTypeArguments(); 1151 const bool has_type_arguments = cls.HasTypeArguments();
1152 1152
1153 __ EnterStubFrame(true); // Uses pool pointer to refer to function. 1153 __ EnterStubFrame(true); // Uses pool pointer to refer to function.
1154 const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize; 1154 const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize;
1155 const intptr_t kReceiverFPOffset = 4 * kWordSize; 1155 const intptr_t kReceiverFPOffset = 4 * kWordSize;
1156 const intptr_t closure_size = Closure::InstanceSize(); 1156 const intptr_t closure_size = Closure::InstanceSize();
1157 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1157 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 __ LoadImmediate(R0, tags); 1192 __ LoadImmediate(R0, tags);
1193 __ str(R0, Address(R2, Instance::tags_offset())); 1193 __ str(R0, Address(R2, Instance::tags_offset()));
1194 1194
1195 // Initialize the function field in the object. 1195 // Initialize the function field in the object.
1196 // R2: new closure object. 1196 // R2: new closure object.
1197 // R4: new context object (only if is_implicit_closure). 1197 // R4: new context object (only if is_implicit_closure).
1198 __ LoadObject(R0, func); // Load function of closure to be allocated. 1198 __ LoadObject(R0, func); // Load function of closure to be allocated.
1199 __ str(R0, Address(R2, Closure::function_offset())); 1199 __ str(R0, Address(R2, Closure::function_offset()));
1200 1200
1201 // Setup the context for this closure. 1201 // Setup the context for this closure.
1202 if (is_implicit_static_closure) { 1202 if (is_implicit_instance_closure) {
1203 ObjectStore* object_store = Isolate::Current()->object_store();
1204 ASSERT(object_store != NULL);
1205 const Context& empty_context =
1206 Context::ZoneHandle(object_store->empty_context());
1207 __ LoadObject(R0, empty_context);
1208 __ str(R0, Address(R2, Closure::context_offset()));
1209 } else if (is_implicit_instance_closure) {
1210 // Initialize the new context capturing the receiver. 1203 // Initialize the new context capturing the receiver.
1211 const Class& context_class = Class::ZoneHandle(Object::context_class()); 1204 const Class& context_class = Class::ZoneHandle(Object::context_class());
1212 // Set the tags. 1205 // Set the tags.
1213 uword tags = 0; 1206 uword tags = 0;
1214 tags = RawObject::SizeTag::update(context_size, tags); 1207 tags = RawObject::SizeTag::update(context_size, tags);
1215 tags = RawObject::ClassIdTag::update(context_class.id(), tags); 1208 tags = RawObject::ClassIdTag::update(context_class.id(), tags);
1216 __ LoadImmediate(R0, tags); 1209 __ LoadImmediate(R0, tags);
1217 __ str(R0, Address(R4, Context::tags_offset())); 1210 __ str(R0, Address(R4, Context::tags_offset()));
1218 1211
1219 // Set number of variables field to 1 (for captured receiver). 1212 // Set number of variables field to 1 (for captured receiver).
(...skipping 28 matching lines...) Expand all
1248 __ add(R0, R2, ShifterOperand(kHeapObjectTag)); 1241 __ add(R0, R2, ShifterOperand(kHeapObjectTag));
1249 // R0: new object. 1242 // R0: new object.
1250 __ LeaveStubFrame(true); 1243 __ LeaveStubFrame(true);
1251 __ Ret(); 1244 __ Ret();
1252 1245
1253 __ Bind(&slow_case); 1246 __ Bind(&slow_case);
1254 } 1247 }
1255 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1248 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1256 __ Push(R0); // Setup space on stack for return value. 1249 __ Push(R0); // Setup space on stack for return value.
1257 __ PushObject(func); 1250 __ PushObject(func);
1258 if (is_implicit_static_closure) { 1251 if (is_implicit_instance_closure) {
1259 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); 1252 __ ldr(R1, Address(FP, kReceiverFPOffset));
1253 __ Push(R1); // Receiver.
1254 }
1255 // R0: raw null.
1256 if (has_type_arguments) {
1257 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
1258 }
1259 __ Push(R0); // Push type arguments of closure to be allocated or null.
1260
1261 if (is_implicit_instance_closure) {
1262 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
1263 __ Drop(2); // Pop arguments (type arguments of object and receiver).
1260 } else { 1264 } else {
1261 if (is_implicit_instance_closure) { 1265 ASSERT(func.IsNonImplicitClosureFunction());
1262 __ ldr(R1, Address(FP, kReceiverFPOffset)); 1266 __ CallRuntime(kAllocateClosureRuntimeEntry);
1263 __ Push(R1); // Receiver. 1267 __ Drop(1); // Pop argument (type arguments of object).
1264 }
1265 // R0: raw null.
1266 if (has_type_arguments) {
1267 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
1268 }
1269 __ Push(R0); // Push type arguments of closure to be allocated or null.
1270
1271 if (is_implicit_instance_closure) {
1272 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry);
1273 __ Drop(2); // Pop arguments (type arguments of object and receiver).
1274 } else {
1275 ASSERT(func.IsNonImplicitClosureFunction());
1276 __ CallRuntime(kAllocateClosureRuntimeEntry);
1277 __ Drop(1); // Pop argument (type arguments of object).
1278 }
1279 } 1268 }
1280 __ Drop(1); // Pop function object. 1269 __ Drop(1); // Pop function object.
1281 __ Pop(R0); 1270 __ Pop(R0);
1282 // R0: new object 1271 // R0: new object
1283 // Restore the frame pointer. 1272 // Restore the frame pointer.
1284 __ LeaveStubFrame(true); 1273 __ LeaveStubFrame(true);
1285 __ Ret(); 1274 __ Ret();
1286 } 1275 }
1287 1276
1288 1277
(...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 __ ldr(left, Address(SP, 4 * kWordSize)); 2092 __ ldr(left, Address(SP, 4 * kWordSize));
2104 __ ldr(right, Address(SP, 3 * kWordSize)); 2093 __ ldr(right, Address(SP, 3 * kWordSize));
2105 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2094 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2106 __ PopList((1 << R0) | (1 << R1) | (1 << R2)); 2095 __ PopList((1 << R0) | (1 << R1) | (1 << R2));
2107 __ Ret(); 2096 __ Ret();
2108 } 2097 }
2109 2098
2110 } // namespace dart 2099 } // namespace dart
2111 2100
2112 #endif // defined TARGET_ARCH_ARM 2101 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698