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

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

Issue 178233003: Allocate instance closures similarly to regular closures, i.e. without a (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 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.cc ('k') | runtime/vm/stub_code_ia32.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_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 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. 1213 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
1214 __ Drop(2); // Pop arguments. 1214 __ Drop(2); // Pop arguments.
1215 __ Pop(R0); // Pop result (newly allocated object). 1215 __ Pop(R0); // Pop result (newly allocated object).
1216 // R0: new object 1216 // R0: new object
1217 // Restore the frame pointer. 1217 // Restore the frame pointer.
1218 __ LeaveStubFrame(); 1218 __ LeaveStubFrame();
1219 __ Ret(); 1219 __ Ret();
1220 } 1220 }
1221 1221
1222 1222
1223 // Called for inline allocation of closures.
1224 // Input parameters:
1225 // LR : return address.
1226 // SP + 4 : receiver (null if not an implicit instance closure).
1227 // SP + 0 : type arguments object (null if class is no parameterized).
1228 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1229 const Function& func) {
1230 ASSERT(func.IsClosureFunction());
1231 ASSERT(!func.IsImplicitStaticClosureFunction());
1232 const bool is_implicit_instance_closure =
1233 func.IsImplicitInstanceClosureFunction();
1234 const Class& cls = Class::ZoneHandle(func.signature_class());
1235 const bool has_type_arguments = cls.NumTypeArguments() > 0;
1236
1237 __ EnterStubFrame(true); // Uses pool pointer to refer to function.
1238 const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize;
1239 const intptr_t kReceiverFPOffset = 4 * kWordSize;
1240 const intptr_t closure_size = Closure::InstanceSize();
1241 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1242 if (FLAG_inline_alloc &&
1243 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
1244 Label slow_case;
1245 Heap* heap = Isolate::Current()->heap();
1246 __ LoadImmediate(R5, heap->TopAddress());
1247 __ ldr(R2, Address(R5, 0));
1248 __ AddImmediate(R3, R2, closure_size);
1249 if (is_implicit_instance_closure) {
1250 __ mov(R4, ShifterOperand(R3)); // R4: new context address.
1251 __ AddImmediate(R3, context_size);
1252 }
1253 // Check if the allocation fits into the remaining space.
1254 // R2: potential new closure object.
1255 // R3: potential next object start.
1256 // R4: potential new context object (only if is_implicit_closure).
1257 __ LoadImmediate(IP, heap->EndAddress());
1258 __ ldr(IP, Address(IP, 0));
1259 __ cmp(R3, ShifterOperand(IP));
1260 if (FLAG_use_slow_path) {
1261 __ b(&slow_case);
1262 } else {
1263 __ b(&slow_case, CS); // Branch if unsigned higher or equal.
1264 }
1265
1266 // Successfully allocated the object, now update top to point to
1267 // next object start and initialize the object.
1268 __ str(R3, Address(R5, 0));
1269
1270 if (is_implicit_instance_closure) {
1271 // This closure allocates a context, update allocation stats.
1272 // R3: context size.
1273 __ LoadImmediate(R3, context_size);
1274 // R5: Clobbered.
1275 __ UpdateAllocationStatsWithSize(kContextCid, R3, R5);
1276 }
1277 // The closure allocation is attributed to the signature class.
1278 // R5: Will be clobbered.
1279 __ UpdateAllocationStats(cls.id(), R5);
1280
1281 // R2: new closure object.
1282 // R4: new context object (only if is_implicit_closure).
1283 // Set the tags.
1284 uword tags = 0;
1285 tags = RawObject::SizeTag::update(closure_size, tags);
1286 tags = RawObject::ClassIdTag::update(cls.id(), tags);
1287 __ LoadImmediate(R0, tags);
1288 __ str(R0, Address(R2, Instance::tags_offset()));
1289
1290 // Initialize the function field in the object.
1291 // R2: new closure object.
1292 // R4: new context object (only if is_implicit_closure).
1293 __ LoadObject(R0, func); // Load function of closure to be allocated.
1294 __ str(R0, Address(R2, Closure::function_offset()));
1295
1296 // Setup the context for this closure.
1297 if (is_implicit_instance_closure) {
1298 // Initialize the new context capturing the receiver.
1299 const Class& context_class = Class::ZoneHandle(Object::context_class());
1300 // Set the tags.
1301 uword tags = 0;
1302 tags = RawObject::SizeTag::update(context_size, tags);
1303 tags = RawObject::ClassIdTag::update(context_class.id(), tags);
1304 __ LoadImmediate(R0, tags);
1305 __ str(R0, Address(R4, Context::tags_offset()));
1306
1307 // Set number of variables field to 1 (for captured receiver).
1308 __ LoadImmediate(R0, 1);
1309 __ str(R0, Address(R4, Context::num_variables_offset()));
1310
1311 // Set isolate field to isolate of current context.
1312 __ ldr(R0, FieldAddress(CTX, Context::isolate_offset()));
1313 __ str(R0, Address(R4, Context::isolate_offset()));
1314
1315 // Set the parent to null.
1316 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1317 __ str(R0, Address(R4, Context::parent_offset()));
1318
1319 // Initialize the context variable to the receiver.
1320 __ ldr(R0, Address(FP, kReceiverFPOffset));
1321 __ str(R0, Address(R4, Context::variable_offset(0)));
1322
1323 // Set the newly allocated context in the newly allocated closure.
1324 __ add(R1, R4, ShifterOperand(kHeapObjectTag));
1325 __ str(R1, Address(R2, Closure::context_offset()));
1326 } else {
1327 __ str(CTX, Address(R2, Closure::context_offset()));
1328 }
1329
1330 // Set the type arguments field in the newly allocated closure.
1331 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
1332 __ str(R0, Address(R2, Closure::type_arguments_offset()));
1333
1334 // Done allocating and initializing the instance.
1335 // R2: new object still missing its heap tag.
1336 __ add(R0, R2, ShifterOperand(kHeapObjectTag));
1337 // R0: new object.
1338 __ LeaveStubFrame();
1339 __ Ret();
1340
1341 __ Bind(&slow_case);
1342 }
1343 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1344 __ Push(R0); // Setup space on stack for return value.
1345 __ PushObject(func);
1346 if (is_implicit_instance_closure) {
1347 __ ldr(R1, Address(FP, kReceiverFPOffset));
1348 __ Push(R1); // Receiver.
1349 }
1350 // R0: raw null.
1351 if (has_type_arguments) {
1352 __ ldr(R0, Address(FP, kTypeArgumentsFPOffset));
1353 }
1354 __ Push(R0); // Push type arguments of closure to be allocated or null.
1355
1356 if (is_implicit_instance_closure) {
1357 __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3);
1358 __ Drop(2); // Pop arguments (type arguments of object and receiver).
1359 } else {
1360 ASSERT(func.IsNonImplicitClosureFunction());
1361 __ CallRuntime(kAllocateClosureRuntimeEntry, 2);
1362 __ Drop(1); // Pop argument (type arguments of object).
1363 }
1364 __ Drop(1); // Pop function object.
1365 __ Pop(R0);
1366 // R0: new object
1367 // Restore the frame pointer.
1368 __ LeaveStubFrame();
1369 __ Ret();
1370 }
1371
1372
1373 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function 1223 // Called for invoking "dynamic noSuchMethod(Invocation invocation)" function
1374 // from the entry code of a dart function after an error in passed argument 1224 // from the entry code of a dart function after an error in passed argument
1375 // name or number is detected. 1225 // name or number is detected.
1376 // Input parameters: 1226 // Input parameters:
1377 // LR : return address. 1227 // LR : return address.
1378 // SP : address of last argument. 1228 // SP : address of last argument.
1379 // R5: inline cache data object. 1229 // R5: inline cache data object.
1380 // R4: arguments descriptor array. 1230 // R4: arguments descriptor array.
1381 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1231 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1382 __ EnterStubFrame(); 1232 __ EnterStubFrame();
(...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 const Register right = R0; 1943 const Register right = R0;
2094 __ ldr(left, Address(SP, 1 * kWordSize)); 1944 __ ldr(left, Address(SP, 1 * kWordSize));
2095 __ ldr(right, Address(SP, 0 * kWordSize)); 1945 __ ldr(right, Address(SP, 0 * kWordSize));
2096 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1946 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2097 __ Ret(); 1947 __ Ret();
2098 } 1948 }
2099 1949
2100 } // namespace dart 1950 } // namespace dart
2101 1951
2102 #endif // defined TARGET_ARCH_ARM 1952 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/stub_code.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698