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

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

Issue 1311013008: [builtins] Unify the various versions of [[Call]] with a Call builtin. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: AssertFunction was wrong Created 5 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
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/arm64/code-stubs-arm64.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM64 5 #if V8_TARGET_ARCH_ARM64
6 6
7 #include "src/arm64/frames-arm64.h" 7 #include "src/arm64/frames-arm64.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/debug/debug.h" 9 #include "src/debug/debug.h"
10 #include "src/deoptimizer.h" 10 #include "src/deoptimizer.h"
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 } 1283 }
1284 __ Jump(masm->isolate()->builtins()->OnStackReplacement(), 1284 __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
1285 RelocInfo::CODE_TARGET); 1285 RelocInfo::CODE_TARGET);
1286 1286
1287 __ Bind(&ok); 1287 __ Bind(&ok);
1288 __ Ret(); 1288 __ Ret();
1289 } 1289 }
1290 1290
1291 1291
1292 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { 1292 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
1293 enum {
1294 call_type_JS_func = 0,
1295 call_type_func_proxy = 1,
1296 call_type_non_func = 2
1297 };
1298 Register argc = x0; 1293 Register argc = x0;
1299 Register function = x1; 1294 Register function = x1;
1300 Register call_type = x4;
1301 Register scratch1 = x10; 1295 Register scratch1 = x10;
1302 Register scratch2 = x11; 1296 Register scratch2 = x11;
1303 Register receiver_type = x13;
1304 1297
1305 ASM_LOCATION("Builtins::Generate_FunctionCall"); 1298 ASM_LOCATION("Builtins::Generate_FunctionCall");
1306 // 1. Make sure we have at least one argument. 1299 // 1. Make sure we have at least one argument.
1307 { Label done; 1300 {
1301 Label done;
1308 __ Cbnz(argc, &done); 1302 __ Cbnz(argc, &done);
1309 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex); 1303 __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
1310 __ Push(scratch1); 1304 __ Push(scratch1);
1311 __ Mov(argc, 1); 1305 __ Mov(argc, 1);
1312 __ Bind(&done); 1306 __ Bind(&done);
1313 } 1307 }
1314 1308
1315 // 2. Get the function to call (passed as receiver) from the stack, check 1309 // 2. Get the callable to call (passed as receiver) from the stack.
1316 // if it is a function.
1317 Label slow, non_function;
1318 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); 1310 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2));
1319 __ JumpIfSmi(function, &non_function);
1320 __ JumpIfNotObjectType(function, scratch1, receiver_type,
1321 JS_FUNCTION_TYPE, &slow);
1322 1311
1323 // 3a. Patch the first argument if necessary when calling a function. 1312 // 3. Shift arguments and return address one slot down on the stack
1324 Label shift_arguments;
1325 __ Mov(call_type, static_cast<int>(call_type_JS_func));
1326 { Label convert_to_object, use_global_proxy, patch_receiver;
1327 // Change context eagerly in case we need the global receiver.
1328 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset));
1329
1330 // Do not transform the receiver for strict mode functions.
1331 // Also do not transform the receiver for native (Compilerhints already in
1332 // x3).
1333 __ Ldr(scratch1,
1334 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
1335 __ Ldr(scratch2.W(),
1336 FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset));
1337 __ TestAndBranchIfAnySet(
1338 scratch2.W(),
1339 (1 << SharedFunctionInfo::kStrictModeFunction) |
1340 (1 << SharedFunctionInfo::kNative),
1341 &shift_arguments);
1342
1343 // Compute the receiver in sloppy mode.
1344 Register receiver = x2;
1345 __ Sub(scratch1, argc, 1);
1346 __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeLog2));
1347 __ JumpIfSmi(receiver, &convert_to_object);
1348
1349 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
1350 &use_global_proxy);
1351 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy);
1352
1353 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1354 __ JumpIfObjectType(receiver, scratch1, scratch2,
1355 FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge);
1356
1357 __ Bind(&convert_to_object);
1358
1359 {
1360 // Enter an internal frame in order to preserve argument count.
1361 FrameScope scope(masm, StackFrame::INTERNAL);
1362 __ SmiTag(argc);
1363
1364 __ Push(argc);
1365 __ Mov(x0, receiver);
1366 ToObjectStub stub(masm->isolate());
1367 __ CallStub(&stub);
1368 __ Mov(receiver, x0);
1369
1370 __ Pop(argc);
1371 __ SmiUntag(argc);
1372
1373 // Exit the internal frame.
1374 }
1375
1376 // Restore the function and flag in the registers.
1377 __ Peek(function, Operand(argc, LSL, kXRegSizeLog2));
1378 __ Mov(call_type, static_cast<int>(call_type_JS_func));
1379 __ B(&patch_receiver);
1380
1381 __ Bind(&use_global_proxy);
1382 __ Ldr(receiver, GlobalObjectMemOperand());
1383 __ Ldr(receiver,
1384 FieldMemOperand(receiver, GlobalObject::kGlobalProxyOffset));
1385
1386
1387 __ Bind(&patch_receiver);
1388 __ Sub(scratch1, argc, 1);
1389 __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeLog2));
1390
1391 __ B(&shift_arguments);
1392 }
1393
1394 // 3b. Check for function proxy.
1395 __ Bind(&slow);
1396 __ Mov(call_type, static_cast<int>(call_type_func_proxy));
1397 __ Cmp(receiver_type, JS_FUNCTION_PROXY_TYPE);
1398 __ B(eq, &shift_arguments);
1399 __ Bind(&non_function);
1400 __ Mov(call_type, static_cast<int>(call_type_non_func));
1401
1402 // 3c. Patch the first argument when calling a non-function. The
1403 // CALL_NON_FUNCTION builtin expects the non-function callee as
1404 // receiver, so overwrite the first argument which will ultimately
1405 // become the receiver.
1406 // call type (0: JS function, 1: function proxy, 2: non-function)
1407 __ Sub(scratch1, argc, 1);
1408 __ Poke(function, Operand(scratch1, LSL, kXRegSizeLog2));
1409
1410 // 4. Shift arguments and return address one slot down on the stack
1411 // (overwriting the original receiver). Adjust argument count to make 1313 // (overwriting the original receiver). Adjust argument count to make
1412 // the original first argument the new receiver. 1314 // the original first argument the new receiver.
1413 // call type (0: JS function, 1: function proxy, 2: non-function) 1315 {
1414 __ Bind(&shift_arguments); 1316 Label loop;
1415 { Label loop;
1416 // Calculate the copy start address (destination). Copy end address is jssp. 1317 // Calculate the copy start address (destination). Copy end address is jssp.
1417 __ Add(scratch2, jssp, Operand(argc, LSL, kPointerSizeLog2)); 1318 __ Add(scratch2, jssp, Operand(argc, LSL, kPointerSizeLog2));
1418 __ Sub(scratch1, scratch2, kPointerSize); 1319 __ Sub(scratch1, scratch2, kPointerSize);
1419 1320
1420 __ Bind(&loop); 1321 __ Bind(&loop);
1421 __ Ldr(x12, MemOperand(scratch1, -kPointerSize, PostIndex)); 1322 __ Ldr(x12, MemOperand(scratch1, -kPointerSize, PostIndex));
1422 __ Str(x12, MemOperand(scratch2, -kPointerSize, PostIndex)); 1323 __ Str(x12, MemOperand(scratch2, -kPointerSize, PostIndex));
1423 __ Cmp(scratch1, jssp); 1324 __ Cmp(scratch1, jssp);
1424 __ B(ge, &loop); 1325 __ B(ge, &loop);
1425 // Adjust the actual number of arguments and remove the top element 1326 // Adjust the actual number of arguments and remove the top element
1426 // (which is a copy of the last argument). 1327 // (which is a copy of the last argument).
1427 __ Sub(argc, argc, 1); 1328 __ Sub(argc, argc, 1);
1428 __ Drop(1); 1329 __ Drop(1);
1429 } 1330 }
1430 1331
1431 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, 1332 // 4. Call the callable.
1432 // or a function proxy via CALL_FUNCTION_PROXY. 1333 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1433 // call type (0: JS function, 1: function proxy, 2: non-function)
1434 { Label js_function, non_proxy;
1435 __ Cbz(call_type, &js_function);
1436 // Expected number of arguments is 0 for CALL_NON_FUNCTION.
1437 __ Mov(x2, 0);
1438 __ Cmp(call_type, static_cast<int>(call_type_func_proxy));
1439 __ B(ne, &non_proxy);
1440
1441 __ Push(function); // Re-add proxy object as additional argument.
1442 __ Add(argc, argc, 1);
1443 __ GetBuiltinFunction(function, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
1444 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1445 RelocInfo::CODE_TARGET);
1446
1447 __ Bind(&non_proxy);
1448 __ GetBuiltinFunction(function, Context::CALL_NON_FUNCTION_BUILTIN_INDEX);
1449 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1450 RelocInfo::CODE_TARGET);
1451 __ Bind(&js_function);
1452 }
1453
1454 // 5b. Get the code to call from the function and check that the number of
1455 // expected arguments matches what we're providing. If so, jump
1456 // (tail-call) to the code in register edx without checking arguments.
1457 __ Ldr(x3, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
1458 __ Ldrsw(x2,
1459 FieldMemOperand(x3,
1460 SharedFunctionInfo::kFormalParameterCountOffset));
1461 Label dont_adapt_args;
1462 __ Cmp(x2, argc); // Check formal and actual parameter counts.
1463 __ B(eq, &dont_adapt_args);
1464 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1465 RelocInfo::CODE_TARGET);
1466 __ Bind(&dont_adapt_args);
1467
1468 __ Ldr(x3, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
1469 ParameterCount expected(0);
1470 __ InvokeCode(x3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1471 } 1334 }
1472 1335
1473 1336
1474 static void Generate_PushAppliedArguments(MacroAssembler* masm, 1337 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1475 const int argumentsOffset, 1338 const int argumentsOffset,
1476 const int indexOffset, 1339 const int indexOffset,
1477 const int limitOffset) { 1340 const int limitOffset) {
1478 Label entry, loop; 1341 Label entry, loop;
1479 Register receiver = LoadDescriptor::ReceiverRegister(); 1342 Register receiver = LoadDescriptor::ReceiverRegister();
1480 Register key = LoadDescriptor::NameRegister(); 1343 Register key = LoadDescriptor::NameRegister();
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1546 if (targetIsArgument) { 1409 if (targetIsArgument) {
1547 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX, 1410 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
1548 CALL_FUNCTION); 1411 CALL_FUNCTION);
1549 } else { 1412 } else {
1550 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION); 1413 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
1551 } 1414 }
1552 Register argc = x0; 1415 Register argc = x0;
1553 1416
1554 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged); 1417 Generate_CheckStackOverflow(masm, kFunctionOffset, argc, kArgcIsSmiTagged);
1555 1418
1556 // Push current limit and index. 1419 // Push current limit, index and receiver.
1557 __ Mov(x1, 0); // Initial index. 1420 __ Mov(x1, 0); // Initial index.
1558 __ Push(argc, x1);
1559
1560 Label push_receiver;
1561 __ Ldr(receiver, MemOperand(fp, kReceiverOffset)); 1421 __ Ldr(receiver, MemOperand(fp, kReceiverOffset));
1562 1422 __ Push(argc, x1, receiver);
1563 // Check that the function is a JS function. Otherwise it must be a proxy.
1564 // When it is not the function proxy will be invoked later.
1565 __ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE,
1566 &push_receiver);
1567
1568 // Change context eagerly to get the right global object if necessary.
1569 __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset));
1570 // Load the shared function info.
1571 __ Ldr(x2, FieldMemOperand(function,
1572 JSFunction::kSharedFunctionInfoOffset));
1573
1574 // Compute and push the receiver.
1575 // Do not transform the receiver for strict mode functions.
1576 Label convert_receiver_to_object, use_global_proxy;
1577 __ Ldr(w10, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
1578 __ Tbnz(x10, SharedFunctionInfo::kStrictModeFunction, &push_receiver);
1579 // Do not transform the receiver for native functions.
1580 __ Tbnz(x10, SharedFunctionInfo::kNative, &push_receiver);
1581
1582 // Compute the receiver in sloppy mode.
1583 __ JumpIfSmi(receiver, &convert_receiver_to_object);
1584 __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy);
1585 __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
1586 &use_global_proxy);
1587
1588 // Check if the receiver is already a JavaScript object.
1589 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1590 __ JumpIfObjectType(receiver, x10, x11, FIRST_SPEC_OBJECT_TYPE,
1591 &push_receiver, ge);
1592
1593 // Call a builtin to convert the receiver to a regular object.
1594 __ Bind(&convert_receiver_to_object);
1595 __ Mov(x0, receiver);
1596 ToObjectStub stub(masm->isolate());
1597 __ CallStub(&stub);
1598 __ Mov(receiver, x0);
1599 __ B(&push_receiver);
1600
1601 __ Bind(&use_global_proxy);
1602 __ Ldr(x10, GlobalObjectMemOperand());
1603 __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset));
1604
1605 // Push the receiver
1606 __ Bind(&push_receiver);
1607 __ Push(receiver);
1608 1423
1609 // Copy all arguments from the array to the stack. 1424 // Copy all arguments from the array to the stack.
1610 Generate_PushAppliedArguments( 1425 Generate_PushAppliedArguments(masm, kArgumentsOffset, kIndexOffset,
1611 masm, kArgumentsOffset, kIndexOffset, kLimitOffset); 1426 kLimitOffset);
1612 1427
1613 // At the end of the loop, the number of arguments is stored in 'current', 1428 // At the end of the loop, the number of arguments is stored in x0, untagged
1614 // represented as a smi.
1615 1429
1616 function = x1; // From now on we want the function to be kept in x1; 1430 // Call the callable.
1617 __ Ldr(function, MemOperand(fp, kFunctionOffset)); 1431 // TODO(bmeurer): This should be a tail call according to ES6.
1618 1432 __ Ldr(x1, MemOperand(fp, kFunctionOffset));
1619 // Call the function. 1433 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1620 Label call_proxy;
1621 ParameterCount actual(x0);
1622 __ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE, &call_proxy);
1623 __ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper());
1624 frame_scope.GenerateLeaveFrame();
1625 __ Drop(kStackSize);
1626 __ Ret();
1627
1628 // Call the function proxy.
1629 __ Bind(&call_proxy);
1630 // x0 : argc
1631 // x1 : function
1632 __ Push(function); // Add function proxy as last argument.
1633 __ Add(x0, x0, 1);
1634 __ Mov(x2, 0);
1635 __ GetBuiltinFunction(x1, Context::CALL_FUNCTION_PROXY_BUILTIN_INDEX);
1636 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1637 RelocInfo::CODE_TARGET);
1638 } 1434 }
1639 __ Drop(kStackSize); 1435 __ Drop(kStackSize);
1640 __ Ret(); 1436 __ Ret();
1641 } 1437 }
1642 1438
1643 1439
1644 static void Generate_ConstructHelper(MacroAssembler* masm) { 1440 static void Generate_ConstructHelper(MacroAssembler* masm) {
1645 const int kFormalParameters = 3; 1441 const int kFormalParameters = 3;
1646 const int kStackSize = kFormalParameters + 1; 1442 const int kStackSize = kFormalParameters + 1;
1647 1443
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 // then drop the parameters and the receiver. 1559 // then drop the parameters and the receiver.
1764 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 1560 __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1765 kPointerSize))); 1561 kPointerSize)));
1766 __ Mov(jssp, fp); 1562 __ Mov(jssp, fp);
1767 __ Pop(fp, lr); 1563 __ Pop(fp, lr);
1768 __ DropBySMI(x10, kXRegSize); 1564 __ DropBySMI(x10, kXRegSize);
1769 __ Drop(1); 1565 __ Drop(1);
1770 } 1566 }
1771 1567
1772 1568
1569 // static
1570 void Builtins::Generate_CallFunction(MacroAssembler* masm) {
1571 // ----------- S t a t e -------------
1572 // -- x0 : the number of arguments (not including the receiver)
1573 // -- x1 : the function to call (checked to be a JSFunction)
1574 // -----------------------------------
1575
1576 Label convert, convert_global_proxy, convert_to_object, done_convert;
1577 __ AssertFunction(x1);
1578 // TODO(bmeurer): Throw a TypeError if function's [[FunctionKind]] internal
1579 // slot is "classConstructor".
1580 // Enter the context of the function; ToObject has to run in the function
1581 // context, and we also need to take the global proxy from the function
1582 // context in case of conversion.
1583 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
1584 __ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
1585 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
1586 // We need to convert the receiver for non-native sloppy mode functions.
1587 __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
1588 __ TestAndBranchIfAnySet(w3,
1589 (1 << SharedFunctionInfo::kNative) |
1590 (1 << SharedFunctionInfo::kStrictModeFunction),
1591 &done_convert);
1592 {
1593 __ Peek(x3, Operand(x0, LSL, kXRegSizeLog2));
1594
1595 // ----------- S t a t e -------------
1596 // -- x0 : the number of arguments (not including the receiver)
1597 // -- x1 : the function to call (checked to be a JSFunction)
1598 // -- x2 : the shared function info.
1599 // -- x3 : the receiver
1600 // -- cp : the function context.
1601 // -----------------------------------
1602
1603 Label convert_receiver;
1604 __ JumpIfSmi(x3, &convert_to_object);
1605 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
1606 __ CompareObjectType(x3, x4, x4, FIRST_JS_RECEIVER_TYPE);
1607 __ B(hs, &done_convert);
1608 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &convert_global_proxy);
1609 __ JumpIfNotRoot(x3, Heap::kNullValueRootIndex, &convert_to_object);
1610 __ Bind(&convert_global_proxy);
1611 {
1612 // Patch receiver to global proxy.
1613 __ LoadGlobalProxy(x3);
1614 }
1615 __ B(&convert_receiver);
1616 __ Bind(&convert_to_object);
1617 {
1618 // Convert receiver using ToObject.
1619 // TODO(bmeurer): Inline the allocation here to avoid building the frame
1620 // in the fast case? (fall back to AllocateInNewSpace?)
1621 FrameScope scope(masm, StackFrame::INTERNAL);
1622 __ SmiTag(x0);
1623 __ Push(x0, x1);
1624 __ Mov(x0, x3);
1625 ToObjectStub stub(masm->isolate());
1626 __ CallStub(&stub);
1627 __ Mov(x3, x0);
1628 __ Pop(x1, x0);
1629 __ SmiUntag(x0);
1630 }
1631 __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
1632 __ Bind(&convert_receiver);
1633 __ Poke(x3, Operand(x0, LSL, kXRegSizeLog2));
1634 }
1635 __ Bind(&done_convert);
1636
1637 // ----------- S t a t e -------------
1638 // -- x0 : the number of arguments (not including the receiver)
1639 // -- x1 : the function to call (checked to be a JSFunction)
1640 // -- x2 : the shared function info.
1641 // -- cp : the function context.
1642 // -----------------------------------
1643
1644 __ Ldrsw(
1645 x2, FieldMemOperand(x2, SharedFunctionInfo::kFormalParameterCountOffset));
1646 __ Ldr(x3, FieldMemOperand(x1, JSFunction::kCodeEntryOffset));
1647 ParameterCount actual(x0);
1648 ParameterCount expected(x2);
1649 __ InvokeCode(x3, expected, actual, JUMP_FUNCTION, NullCallWrapper());
1650 }
1651
1652
1653 // static
1654 void Builtins::Generate_Call(MacroAssembler* masm) {
1655 // ----------- S t a t e -------------
1656 // -- x0 : the number of arguments (not including the receiver)
1657 // -- x1 : the target to call (can be any Object).
1658 // -----------------------------------
1659
1660 Label non_smi, non_jsfunction, non_function;
1661 __ JumpIfSmi(x1, &non_function);
1662 __ Bind(&non_smi);
1663 __ CompareObjectType(x1, x2, x2, JS_FUNCTION_TYPE);
1664 __ B(ne, &non_jsfunction);
1665 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1666 __ Bind(&non_jsfunction);
1667 __ Cmp(x2, JS_FUNCTION_PROXY_TYPE);
1668 __ B(ne, &non_function);
1669
1670 // 1. Call to function proxy.
1671 // TODO(neis): This doesn't match the ES6 spec for [[Call]] on proxies.
1672 __ Ldr(x1, FieldMemOperand(x1, JSFunctionProxy::kCallTrapOffset));
1673 __ AssertNotSmi(x1);
1674 __ B(&non_smi);
1675
1676 // 2. Call to something else, which might have a [[Call]] internal method (if
1677 // not we raise an exception).
1678 __ Bind(&non_function);
1679 // TODO(bmeurer): I wonder why we prefer to have slow API calls? This could
1680 // be awesome instead; i.e. a trivial improvement would be to call into the
1681 // runtime and just deal with the API function there instead of returning a
1682 // delegate from a runtime call that just jumps back to the runtime once
1683 // called. Or, bonus points, call directly into the C API function here, as
1684 // we do in some Crankshaft fast cases.
1685 // Overwrite the original receiver with the (original) target.
1686 __ Poke(x1, Operand(x0, LSL, kXRegSizeLog2));
1687 {
1688 // Determine the delegate for the target (if any).
1689 FrameScope scope(masm, StackFrame::INTERNAL);
1690 __ SmiTag(x0);
1691 __ Push(x0, x1);
1692 __ CallRuntime(Runtime::kGetFunctionDelegate, 1);
1693 __ Mov(x1, x0);
1694 __ Pop(x0);
1695 __ SmiUntag(x0);
1696 }
1697 // The delegate is always a regular function.
1698 __ AssertFunction(x1);
1699 __ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
1700 }
1701
1702
1773 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 1703 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1774 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); 1704 ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
1775 // ----------- S t a t e ------------- 1705 // ----------- S t a t e -------------
1776 // -- x0 : actual number of arguments 1706 // -- x0 : actual number of arguments
1777 // -- x1 : function (passed through to callee) 1707 // -- x1 : function (passed through to callee)
1778 // -- x2 : expected number of arguments 1708 // -- x2 : expected number of arguments
1779 // ----------------------------------- 1709 // -----------------------------------
1780 1710
1781 Label stack_overflow; 1711 Label stack_overflow;
1782 ArgumentAdaptorStackCheck(masm, &stack_overflow); 1712 ArgumentAdaptorStackCheck(masm, &stack_overflow);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1938 } 1868 }
1939 } 1869 }
1940 1870
1941 1871
1942 #undef __ 1872 #undef __
1943 1873
1944 } // namespace internal 1874 } // namespace internal
1945 } // namespace v8 1875 } // namespace v8
1946 1876
1947 #endif // V8_TARGET_ARCH_ARM 1877 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | src/arm64/code-stubs-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698