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

Side by Side Diff: src/arm/builtins-arm.cc

Issue 7623011: Implement function proxies (except for their use as constructors). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed second round of comments. Created 9 years, 3 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 | « no previous file | src/arm/code-stubs-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 __ b(ne, &done); 1223 __ b(ne, &done);
1224 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 1224 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1225 __ push(r2); 1225 __ push(r2);
1226 __ add(r0, r0, Operand(1)); 1226 __ add(r0, r0, Operand(1));
1227 __ bind(&done); 1227 __ bind(&done);
1228 } 1228 }
1229 1229
1230 // 2. Get the function to call (passed as receiver) from the stack, check 1230 // 2. Get the function to call (passed as receiver) from the stack, check
1231 // if it is a function. 1231 // if it is a function.
1232 // r0: actual number of arguments 1232 // r0: actual number of arguments
1233 Label non_function; 1233 Label slow, non_function;
1234 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); 1234 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1235 __ JumpIfSmi(r1, &non_function); 1235 __ JumpIfSmi(r1, &non_function);
1236 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 1236 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
1237 __ b(ne, &non_function); 1237 __ b(ne, &slow);
1238 1238
1239 // 3a. Patch the first argument if necessary when calling a function. 1239 // 3a. Patch the first argument if necessary when calling a function.
1240 // r0: actual number of arguments 1240 // r0: actual number of arguments
1241 // r1: function 1241 // r1: function
1242 Label shift_arguments; 1242 Label shift_arguments;
1243 __ mov(r4, Operand(0, RelocInfo::NONE)); // indicate regular JS_FUNCTION
1243 { Label convert_to_object, use_global_receiver, patch_receiver; 1244 { Label convert_to_object, use_global_receiver, patch_receiver;
1244 // Change context eagerly in case we need the global receiver. 1245 // Change context eagerly in case we need the global receiver.
1245 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 1246 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
1246 1247
1247 // Do not transform the receiver for strict mode functions. 1248 // Do not transform the receiver for strict mode functions.
1248 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1249 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1249 __ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset)); 1250 __ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
1250 __ tst(r3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 1251 __ tst(r3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1251 kSmiTagSize))); 1252 kSmiTagSize)));
1252 __ b(ne, &shift_arguments); 1253 __ b(ne, &shift_arguments);
(...skipping 26 matching lines...) Expand all
1279 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); // Smi-tagged. 1280 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); // Smi-tagged.
1280 __ push(r0); 1281 __ push(r0);
1281 1282
1282 __ push(r2); 1283 __ push(r2);
1283 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1284 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1284 __ mov(r2, r0); 1285 __ mov(r2, r0);
1285 1286
1286 __ pop(r0); 1287 __ pop(r0);
1287 __ mov(r0, Operand(r0, ASR, kSmiTagSize)); 1288 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
1288 __ LeaveInternalFrame(); 1289 __ LeaveInternalFrame();
1289 // Restore the function to r1. 1290 // Restore the function to r1, and the flag to r4.
1290 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); 1291 __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1292 __ mov(r4, Operand(0, RelocInfo::NONE));
1291 __ jmp(&patch_receiver); 1293 __ jmp(&patch_receiver);
1292 1294
1293 // Use the global receiver object from the called function as the 1295 // Use the global receiver object from the called function as the
1294 // receiver. 1296 // receiver.
1295 __ bind(&use_global_receiver); 1297 __ bind(&use_global_receiver);
1296 const int kGlobalIndex = 1298 const int kGlobalIndex =
1297 Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; 1299 Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
1298 __ ldr(r2, FieldMemOperand(cp, kGlobalIndex)); 1300 __ ldr(r2, FieldMemOperand(cp, kGlobalIndex));
1299 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset)); 1301 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalContextOffset));
1300 __ ldr(r2, FieldMemOperand(r2, kGlobalIndex)); 1302 __ ldr(r2, FieldMemOperand(r2, kGlobalIndex));
1301 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); 1303 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
1302 1304
1303 __ bind(&patch_receiver); 1305 __ bind(&patch_receiver);
1304 __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2)); 1306 __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2));
1305 __ str(r2, MemOperand(r3, -kPointerSize)); 1307 __ str(r2, MemOperand(r3, -kPointerSize));
1306 1308
1307 __ jmp(&shift_arguments); 1309 __ jmp(&shift_arguments);
1308 } 1310 }
1309 1311
1310 // 3b. Patch the first argument when calling a non-function. The 1312 // 3b. Check for function proxy.
1313 __ bind(&slow);
1314 __ mov(r4, Operand(1, RelocInfo::NONE)); // indicate function proxy
1315 __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE));
1316 __ b(eq, &shift_arguments);
1317 __ bind(&non_function);
1318 __ mov(r4, Operand(2, RelocInfo::NONE)); // indicate non-function
1319
1320 // 3c. Patch the first argument when calling a non-function. The
1311 // CALL_NON_FUNCTION builtin expects the non-function callee as 1321 // CALL_NON_FUNCTION builtin expects the non-function callee as
1312 // receiver, so overwrite the first argument which will ultimately 1322 // receiver, so overwrite the first argument which will ultimately
1313 // become the receiver. 1323 // become the receiver.
1314 // r0: actual number of arguments 1324 // r0: actual number of arguments
1315 // r1: function 1325 // r1: function
1316 __ bind(&non_function); 1326 // r4: call type (0: JS function, 1: function proxy, 2: non-function)
1317 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); 1327 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1318 __ str(r1, MemOperand(r2, -kPointerSize)); 1328 __ str(r1, MemOperand(r2, -kPointerSize));
1319 // Clear r1 to indicate a non-function being called.
1320 __ mov(r1, Operand(0, RelocInfo::NONE));
1321 1329
1322 // 4. Shift arguments and return address one slot down on the stack 1330 // 4. Shift arguments and return address one slot down on the stack
1323 // (overwriting the original receiver). Adjust argument count to make 1331 // (overwriting the original receiver). Adjust argument count to make
1324 // the original first argument the new receiver. 1332 // the original first argument the new receiver.
1325 // r0: actual number of arguments 1333 // r0: actual number of arguments
1326 // r1: function 1334 // r1: function
1335 // r4: call type (0: JS function, 1: function proxy, 2: non-function)
1327 __ bind(&shift_arguments); 1336 __ bind(&shift_arguments);
1328 { Label loop; 1337 { Label loop;
1329 // Calculate the copy start address (destination). Copy end address is sp. 1338 // Calculate the copy start address (destination). Copy end address is sp.
1330 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); 1339 __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1331 1340
1332 __ bind(&loop); 1341 __ bind(&loop);
1333 __ ldr(ip, MemOperand(r2, -kPointerSize)); 1342 __ ldr(ip, MemOperand(r2, -kPointerSize));
1334 __ str(ip, MemOperand(r2)); 1343 __ str(ip, MemOperand(r2));
1335 __ sub(r2, r2, Operand(kPointerSize)); 1344 __ sub(r2, r2, Operand(kPointerSize));
1336 __ cmp(r2, sp); 1345 __ cmp(r2, sp);
1337 __ b(ne, &loop); 1346 __ b(ne, &loop);
1338 // Adjust the actual number of arguments and remove the top element 1347 // Adjust the actual number of arguments and remove the top element
1339 // (which is a copy of the last argument). 1348 // (which is a copy of the last argument).
1340 __ sub(r0, r0, Operand(1)); 1349 __ sub(r0, r0, Operand(1));
1341 __ pop(); 1350 __ pop();
1342 } 1351 }
1343 1352
1344 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. 1353 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
1354 // or a function proxy via CALL_FUNCTION_PROXY.
1345 // r0: actual number of arguments 1355 // r0: actual number of arguments
1346 // r1: function 1356 // r1: function
1347 { Label function; 1357 // r4: call type (0: JS function, 1: function proxy, 2: non-function)
1348 __ tst(r1, r1); 1358 { Label function, non_proxy;
1349 __ b(ne, &function); 1359 __ tst(r4, r4);
1360 __ b(eq, &function);
1350 // Expected number of arguments is 0 for CALL_NON_FUNCTION. 1361 // Expected number of arguments is 0 for CALL_NON_FUNCTION.
1351 __ mov(r2, Operand(0, RelocInfo::NONE)); 1362 __ mov(r2, Operand(0, RelocInfo::NONE));
1363 __ SetCallKind(r5, CALL_AS_METHOD);
1364 __ cmp(r4, Operand(1));
1365 __ b(ne, &non_proxy);
1366
1367 __ push(r1); // re-add proxy object as additional argument
1368 __ add(r0, r0, Operand(1));
1369 __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
1370 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1371 RelocInfo::CODE_TARGET);
1372
1373 __ bind(&non_proxy);
1352 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 1374 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
1353 __ SetCallKind(r5, CALL_AS_METHOD);
1354 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1375 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1355 RelocInfo::CODE_TARGET); 1376 RelocInfo::CODE_TARGET);
1356 __ bind(&function); 1377 __ bind(&function);
1357 } 1378 }
1358 1379
1359 // 5b. Get the code to call from the function and check that the number of 1380 // 5b. Get the code to call from the function and check that the number of
1360 // expected arguments matches what we're providing. If so, jump 1381 // expected arguments matches what we're providing. If so, jump
1361 // (tail-call) to the code in register edx without checking arguments. 1382 // (tail-call) to the code in register edx without checking arguments.
1362 // r0: actual number of arguments 1383 // r0: actual number of arguments
1363 // r1: function 1384 // r1: function
(...skipping 22 matching lines...) Expand all
1386 const int kFunctionOffset = 4 * kPointerSize; 1407 const int kFunctionOffset = 4 * kPointerSize;
1387 1408
1388 __ EnterInternalFrame(); 1409 __ EnterInternalFrame();
1389 1410
1390 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function 1411 __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
1391 __ push(r0); 1412 __ push(r0);
1392 __ ldr(r0, MemOperand(fp, kArgsOffset)); // get the args array 1413 __ ldr(r0, MemOperand(fp, kArgsOffset)); // get the args array
1393 __ push(r0); 1414 __ push(r0);
1394 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1415 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1395 1416
1396 // Check the stack for overflow. We are not trying need to catch 1417 // Check the stack for overflow. We are not trying to catch
1397 // interruptions (e.g. debug break and preemption) here, so the "real stack 1418 // interruptions (e.g. debug break and preemption) here, so the "real stack
1398 // limit" is checked. 1419 // limit" is checked.
1399 Label okay; 1420 Label okay;
1400 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex); 1421 __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
1401 // Make r2 the space we have left. The stack might already be overflowed 1422 // Make r2 the space we have left. The stack might already be overflowed
1402 // here which will cause r2 to become negative. 1423 // here which will cause r2 to become negative.
1403 __ sub(r2, sp, r2); 1424 __ sub(r2, sp, r2);
1404 // Check if the arguments will overflow the stack. 1425 // Check if the arguments will overflow the stack.
1405 __ cmp(r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize)); 1426 __ cmp(r2, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
1406 __ b(gt, &okay); // Signed comparison. 1427 __ b(gt, &okay); // Signed comparison.
1407 1428
1408 // Out of stack space. 1429 // Out of stack space.
1409 __ ldr(r1, MemOperand(fp, kFunctionOffset)); 1430 __ ldr(r1, MemOperand(fp, kFunctionOffset));
1410 __ push(r1); 1431 __ push(r1);
1411 __ push(r0); 1432 __ push(r0);
1412 __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION); 1433 __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
1413 // End of stack check. 1434 // End of stack check.
1414 1435
1415 // Push current limit and index. 1436 // Push current limit and index.
1416 __ bind(&okay); 1437 __ bind(&okay);
1417 __ push(r0); // limit 1438 __ push(r0); // limit
1418 __ mov(r1, Operand(0, RelocInfo::NONE)); // initial index 1439 __ mov(r1, Operand(0, RelocInfo::NONE)); // initial index
1419 __ push(r1); 1440 __ push(r1);
1420 1441
1442 // Get the receiver.
1443 __ ldr(r0, MemOperand(fp, kRecvOffset));
1444
1445 // Check that the function is a JS function (otherwise it must be a proxy).
1446 Label push_receiver;
1447 __ ldr(r1, MemOperand(fp, kFunctionOffset));
1448 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
1449 __ b(ne, &push_receiver);
1450
1421 // Change context eagerly to get the right global object if necessary. 1451 // Change context eagerly to get the right global object if necessary.
1422 __ ldr(r0, MemOperand(fp, kFunctionOffset)); 1452 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
1423 __ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); 1453 // Load the shared function info while the function is still in r1.
1424 // Load the shared function info while the function is still in r0. 1454 __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1425 __ ldr(r1, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
1426 1455
1427 // Compute the receiver. 1456 // Compute the receiver.
1428 Label call_to_object, use_global_receiver, push_receiver;
1429 __ ldr(r0, MemOperand(fp, kRecvOffset));
1430
1431 // Do not transform the receiver for strict mode functions. 1457 // Do not transform the receiver for strict mode functions.
1432 __ ldr(r2, FieldMemOperand(r1, SharedFunctionInfo::kCompilerHintsOffset)); 1458 Label call_to_object, use_global_receiver;
1459 __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
1433 __ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 1460 __ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1434 kSmiTagSize))); 1461 kSmiTagSize)));
1435 __ b(ne, &push_receiver); 1462 __ b(ne, &push_receiver);
1436 1463
1437 // Do not transform the receiver for strict mode functions. 1464 // Do not transform the receiver for strict mode functions.
1438 __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 1465 __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1439 __ b(ne, &push_receiver); 1466 __ b(ne, &push_receiver);
1440 1467
1441 // Compute the receiver in non-strict mode. 1468 // Compute the receiver in non-strict mode.
1442 __ JumpIfSmi(r0, &call_to_object); 1469 __ JumpIfSmi(r0, &call_to_object);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1497 __ str(r0, MemOperand(fp, kIndexOffset)); 1524 __ str(r0, MemOperand(fp, kIndexOffset));
1498 1525
1499 // Test if the copy loop has finished copying all the elements from the 1526 // Test if the copy loop has finished copying all the elements from the
1500 // arguments object. 1527 // arguments object.
1501 __ bind(&entry); 1528 __ bind(&entry);
1502 __ ldr(r1, MemOperand(fp, kLimitOffset)); 1529 __ ldr(r1, MemOperand(fp, kLimitOffset));
1503 __ cmp(r0, r1); 1530 __ cmp(r0, r1);
1504 __ b(ne, &loop); 1531 __ b(ne, &loop);
1505 1532
1506 // Invoke the function. 1533 // Invoke the function.
1534 Label call_proxy;
1507 ParameterCount actual(r0); 1535 ParameterCount actual(r0);
1508 __ mov(r0, Operand(r0, ASR, kSmiTagSize)); 1536 __ mov(r0, Operand(r0, ASR, kSmiTagSize));
1509 __ ldr(r1, MemOperand(fp, kFunctionOffset)); 1537 __ ldr(r1, MemOperand(fp, kFunctionOffset));
1538 __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
1539 __ b(ne, &call_proxy);
1510 __ InvokeFunction(r1, actual, CALL_FUNCTION, 1540 __ InvokeFunction(r1, actual, CALL_FUNCTION,
1511 NullCallWrapper(), CALL_AS_METHOD); 1541 NullCallWrapper(), CALL_AS_METHOD);
1512 1542
1513 // Tear down the internal frame and remove function, receiver and args. 1543 // Tear down the internal frame and remove function, receiver and args.
1514 __ LeaveInternalFrame(); 1544 __ LeaveInternalFrame();
1515 __ add(sp, sp, Operand(3 * kPointerSize)); 1545 __ add(sp, sp, Operand(3 * kPointerSize));
1516 __ Jump(lr); 1546 __ Jump(lr);
1547
1548 // Invoke the function proxy.
1549 __ bind(&call_proxy);
1550 __ push(r1); // add function proxy as last argument
1551 __ add(r0, r0, Operand(1));
1552 __ mov(r2, Operand(0, RelocInfo::NONE));
1553 __ SetCallKind(r5, CALL_AS_METHOD);
1554 __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
1555 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1556 RelocInfo::CODE_TARGET);
1557
1558 __ LeaveInternalFrame();
1559 __ add(sp, sp, Operand(3 * kPointerSize));
1560 __ Jump(lr);
1517 } 1561 }
1518 1562
1519 1563
1520 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1564 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1521 __ mov(r0, Operand(r0, LSL, kSmiTagSize)); 1565 __ mov(r0, Operand(r0, LSL, kSmiTagSize));
1522 __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1566 __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1523 __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | fp.bit() | lr.bit()); 1567 __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | fp.bit() | lr.bit());
1524 __ add(fp, sp, Operand(3 * kPointerSize)); 1568 __ add(fp, sp, Operand(3 * kPointerSize));
1525 } 1569 }
1526 1570
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1642 __ bind(&dont_adapt_arguments); 1686 __ bind(&dont_adapt_arguments);
1643 __ Jump(r3); 1687 __ Jump(r3);
1644 } 1688 }
1645 1689
1646 1690
1647 #undef __ 1691 #undef __
1648 1692
1649 } } // namespace v8::internal 1693 } } // namespace v8::internal
1650 1694
1651 #endif // V8_TARGET_ARCH_ARM 1695 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698