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

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

Issue 7891033: MIPS: port Implement function proxies (except for their use as constructors). (Closed)
Patch Set: Rebased on bleeding_edge, resolved merge problem with r9297 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
« no previous file with comments | « no previous file | src/mips/code-stubs-mips.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 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 __ Branch(&done, ne, a0, Operand(zero_reg)); 1193 __ Branch(&done, ne, a0, Operand(zero_reg));
1194 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); 1194 __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
1195 __ push(t2); 1195 __ push(t2);
1196 __ Addu(a0, a0, Operand(1)); 1196 __ Addu(a0, a0, Operand(1));
1197 __ bind(&done); 1197 __ bind(&done);
1198 } 1198 }
1199 1199
1200 // 2. Get the function to call (passed as receiver) from the stack, check 1200 // 2. Get the function to call (passed as receiver) from the stack, check
1201 // if it is a function. 1201 // if it is a function.
1202 // a0: actual number of arguments 1202 // a0: actual number of arguments
1203 Label non_function; 1203 Label slow, non_function;
1204 __ sll(at, a0, kPointerSizeLog2); 1204 __ sll(at, a0, kPointerSizeLog2);
1205 __ addu(at, sp, at); 1205 __ addu(at, sp, at);
1206 __ lw(a1, MemOperand(at)); 1206 __ lw(a1, MemOperand(at));
1207 __ And(at, a1, Operand(kSmiTagMask)); 1207 __ And(at, a1, Operand(kSmiTagMask));
1208 __ Branch(&non_function, eq, at, Operand(zero_reg)); 1208 __ Branch(&non_function, eq, at, Operand(zero_reg));
1209 __ GetObjectType(a1, a2, a2); 1209 __ GetObjectType(a1, a2, a2);
1210 __ Branch(&non_function, ne, a2, Operand(JS_FUNCTION_TYPE)); 1210 __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE));
1211 1211
1212 // 3a. Patch the first argument if necessary when calling a function. 1212 // 3a. Patch the first argument if necessary when calling a function.
1213 // a0: actual number of arguments 1213 // a0: actual number of arguments
1214 // a1: function 1214 // a1: function
1215 Label shift_arguments; 1215 Label shift_arguments;
1216 __ li(t0, Operand(0, RelocInfo::NONE)); // Indicate regular JS_FUNCTION.
1216 { Label convert_to_object, use_global_receiver, patch_receiver; 1217 { Label convert_to_object, use_global_receiver, patch_receiver;
1217 // Change context eagerly in case we need the global receiver. 1218 // Change context eagerly in case we need the global receiver.
1218 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 1219 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1219 1220
1220 // Do not transform the receiver for strict mode functions. 1221 // Do not transform the receiver for strict mode functions.
1221 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1222 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1222 __ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset)); 1223 __ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
1223 __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 1224 __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1224 kSmiTagSize))); 1225 kSmiTagSize)));
1225 __ Branch(&shift_arguments, ne, t0, Operand(zero_reg)); 1226 __ Branch(&shift_arguments, ne, t3, Operand(zero_reg));
1226 1227
1227 // Do not transform the receiver for native (Compilerhints already in a3). 1228 // Do not transform the receiver for native (Compilerhints already in a3).
1228 __ And(t0, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 1229 __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1229 __ Branch(&shift_arguments, ne, t0, Operand(zero_reg)); 1230 __ Branch(&shift_arguments, ne, t3, Operand(zero_reg));
1230 1231
1231 // Compute the receiver in non-strict mode. 1232 // Compute the receiver in non-strict mode.
1232 // Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2). 1233 // Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2).
1233 __ sll(at, a0, kPointerSizeLog2); 1234 __ sll(at, a0, kPointerSizeLog2);
1234 __ addu(a2, sp, at); 1235 __ addu(a2, sp, at);
1235 __ lw(a2, MemOperand(a2, -kPointerSize)); 1236 __ lw(a2, MemOperand(a2, -kPointerSize));
1236 // a0: actual number of arguments 1237 // a0: actual number of arguments
1237 // a1: function 1238 // a1: function
1238 // a2: first argument 1239 // a2: first argument
1239 __ JumpIfSmi(a2, &convert_to_object, t2); 1240 __ JumpIfSmi(a2, &convert_to_object, t2);
(...skipping 15 matching lines...) Expand all
1255 __ push(a0); 1256 __ push(a0);
1256 1257
1257 __ push(a2); 1258 __ push(a2);
1258 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1259 __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1259 __ mov(a2, v0); 1260 __ mov(a2, v0);
1260 1261
1261 __ pop(a0); 1262 __ pop(a0);
1262 __ sra(a0, a0, kSmiTagSize); // Un-tag. 1263 __ sra(a0, a0, kSmiTagSize); // Un-tag.
1263 // Leave internal frame. 1264 // Leave internal frame.
1264 } 1265 }
1265 // Restore the function to a1. 1266 // Restore the function to a1, and the flag to t0.
1266 __ sll(at, a0, kPointerSizeLog2); 1267 __ sll(at, a0, kPointerSizeLog2);
1267 __ addu(at, sp, at); 1268 __ addu(at, sp, at);
1268 __ lw(a1, MemOperand(at)); 1269 __ lw(a1, MemOperand(at));
1270 __ li(t0, Operand(0, RelocInfo::NONE));
1269 __ Branch(&patch_receiver); 1271 __ Branch(&patch_receiver);
1270 1272
1271 // Use the global receiver object from the called function as the 1273 // Use the global receiver object from the called function as the
1272 // receiver. 1274 // receiver.
1273 __ bind(&use_global_receiver); 1275 __ bind(&use_global_receiver);
1274 const int kGlobalIndex = 1276 const int kGlobalIndex =
1275 Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; 1277 Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
1276 __ lw(a2, FieldMemOperand(cp, kGlobalIndex)); 1278 __ lw(a2, FieldMemOperand(cp, kGlobalIndex));
1277 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalContextOffset)); 1279 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalContextOffset));
1278 __ lw(a2, FieldMemOperand(a2, kGlobalIndex)); 1280 __ lw(a2, FieldMemOperand(a2, kGlobalIndex));
1279 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); 1281 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
1280 1282
1281 __ bind(&patch_receiver); 1283 __ bind(&patch_receiver);
1282 __ sll(at, a0, kPointerSizeLog2); 1284 __ sll(at, a0, kPointerSizeLog2);
1283 __ addu(a3, sp, at); 1285 __ addu(a3, sp, at);
1284 __ sw(a2, MemOperand(a3, -kPointerSize)); 1286 __ sw(a2, MemOperand(a3, -kPointerSize));
1285 1287
1286 __ Branch(&shift_arguments); 1288 __ Branch(&shift_arguments);
1287 } 1289 }
1288 1290
1289 // 3b. Patch the first argument when calling a non-function. The 1291 // 3b. Check for function proxy.
1292 __ bind(&slow);
1293 __ li(t0, Operand(1, RelocInfo::NONE)); // Indicate function proxy.
1294 __ Branch(&shift_arguments, eq, a2, Operand(JS_FUNCTION_PROXY_TYPE));
1295
1296 __ bind(&non_function);
1297 __ li(t0, Operand(2, RelocInfo::NONE)); // Indicate non-function.
1298
1299 // 3c. Patch the first argument when calling a non-function. The
1290 // CALL_NON_FUNCTION builtin expects the non-function callee as 1300 // CALL_NON_FUNCTION builtin expects the non-function callee as
1291 // receiver, so overwrite the first argument which will ultimately 1301 // receiver, so overwrite the first argument which will ultimately
1292 // become the receiver. 1302 // become the receiver.
1293 // a0: actual number of arguments 1303 // a0: actual number of arguments
1294 // a1: function 1304 // a1: function
1295 __ bind(&non_function); 1305 // t0: call type (0: JS function, 1: function proxy, 2: non-function)
1296 // Restore the function in case it has been modified.
1297 __ sll(at, a0, kPointerSizeLog2); 1306 __ sll(at, a0, kPointerSizeLog2);
1298 __ addu(a2, sp, at); 1307 __ addu(a2, sp, at);
1299 __ sw(a1, MemOperand(a2, -kPointerSize)); 1308 __ sw(a1, MemOperand(a2, -kPointerSize));
1300 // Clear a1 to indicate a non-function being called.
1301 __ mov(a1, zero_reg);
1302 1309
1303 // 4. Shift arguments and return address one slot down on the stack 1310 // 4. Shift arguments and return address one slot down on the stack
1304 // (overwriting the original receiver). Adjust argument count to make 1311 // (overwriting the original receiver). Adjust argument count to make
1305 // the original first argument the new receiver. 1312 // the original first argument the new receiver.
1306 // a0: actual number of arguments 1313 // a0: actual number of arguments
1307 // a1: function 1314 // a1: function
1315 // t0: call type (0: JS function, 1: function proxy, 2: non-function)
1308 __ bind(&shift_arguments); 1316 __ bind(&shift_arguments);
1309 { Label loop; 1317 { Label loop;
1310 // Calculate the copy start address (destination). Copy end address is sp. 1318 // Calculate the copy start address (destination). Copy end address is sp.
1311 __ sll(at, a0, kPointerSizeLog2); 1319 __ sll(at, a0, kPointerSizeLog2);
1312 __ addu(a2, sp, at); 1320 __ addu(a2, sp, at);
1313 1321
1314 __ bind(&loop); 1322 __ bind(&loop);
1315 __ lw(at, MemOperand(a2, -kPointerSize)); 1323 __ lw(at, MemOperand(a2, -kPointerSize));
1316 __ sw(at, MemOperand(a2)); 1324 __ sw(at, MemOperand(a2));
1317 __ Subu(a2, a2, Operand(kPointerSize)); 1325 __ Subu(a2, a2, Operand(kPointerSize));
1318 __ Branch(&loop, ne, a2, Operand(sp)); 1326 __ Branch(&loop, ne, a2, Operand(sp));
1319 // Adjust the actual number of arguments and remove the top element 1327 // Adjust the actual number of arguments and remove the top element
1320 // (which is a copy of the last argument). 1328 // (which is a copy of the last argument).
1321 __ Subu(a0, a0, Operand(1)); 1329 __ Subu(a0, a0, Operand(1));
1322 __ Pop(); 1330 __ Pop();
1323 } 1331 }
1324 1332
1325 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. 1333 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
1334 // or a function proxy via CALL_FUNCTION_PROXY.
1326 // a0: actual number of arguments 1335 // a0: actual number of arguments
1327 // a1: function 1336 // a1: function
1328 { Label function; 1337 // t0: call type (0: JS function, 1: function proxy, 2: non-function)
1329 __ Branch(&function, ne, a1, Operand(zero_reg)); 1338 { Label function, non_proxy;
1330 __ mov(a2, zero_reg); // expected arguments is 0 for CALL_NON_FUNCTION 1339 __ Branch(&function, eq, t0, Operand(zero_reg));
1340 // Expected number of arguments is 0 for CALL_NON_FUNCTION.
1341 __ mov(a2, zero_reg);
1342 __ SetCallKind(t1, CALL_AS_METHOD);
1343 __ Branch(&non_proxy, ne, t0, Operand(1));
1344
1345 __ push(a1); // Re-add proxy object as additional argument.
1346 __ Addu(a0, a0, Operand(1));
1347 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
1348 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1349 RelocInfo::CODE_TARGET);
1350
1351 __ bind(&non_proxy);
1331 __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION); 1352 __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION);
1332 __ SetCallKind(t1, CALL_AS_METHOD);
1333 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1353 __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1334 RelocInfo::CODE_TARGET); 1354 RelocInfo::CODE_TARGET);
1335 __ bind(&function); 1355 __ bind(&function);
1336 } 1356 }
1337 1357
1338 // 5b. Get the code to call from the function and check that the number of 1358 // 5b. Get the code to call from the function and check that the number of
1339 // expected arguments matches what we're providing. If so, jump 1359 // expected arguments matches what we're providing. If so, jump
1340 // (tail-call) to the code in register edx without checking arguments. 1360 // (tail-call) to the code in register edx without checking arguments.
1341 // a0: actual number of arguments 1361 // a0: actual number of arguments
1342 // a1: function 1362 // a1: function
(...skipping 14 matching lines...) Expand all
1357 1377
1358 1378
1359 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1379 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1360 const int kIndexOffset = -5 * kPointerSize; 1380 const int kIndexOffset = -5 * kPointerSize;
1361 const int kLimitOffset = -4 * kPointerSize; 1381 const int kLimitOffset = -4 * kPointerSize;
1362 const int kArgsOffset = 2 * kPointerSize; 1382 const int kArgsOffset = 2 * kPointerSize;
1363 const int kRecvOffset = 3 * kPointerSize; 1383 const int kRecvOffset = 3 * kPointerSize;
1364 const int kFunctionOffset = 4 * kPointerSize; 1384 const int kFunctionOffset = 4 * kPointerSize;
1365 1385
1366 { 1386 {
1367 FrameScope scope(masm, StackFrame::INTERNAL); 1387 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1368
1369 __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. 1388 __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
1370 __ push(a0); 1389 __ push(a0);
1371 __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array. 1390 __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array.
1372 __ push(a0); 1391 __ push(a0);
1373 // Returns (in v0) number of arguments to copy to stack as Smi. 1392 // Returns (in v0) number of arguments to copy to stack as Smi.
1374 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1393 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1375 1394
1376 // Check the stack for overflow. We are not trying need to catch 1395 // Check the stack for overflow. We are not trying to catch
1377 // interruptions (e.g. debug break and preemption) here, so the "real stack 1396 // interruptions (e.g. debug break and preemption) here, so the "real stack
1378 // limit" is checked. 1397 // limit" is checked.
1379 Label okay; 1398 Label okay;
1380 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 1399 __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1381 // Make a2 the space we have left. The stack might already be overflowed 1400 // Make a2 the space we have left. The stack might already be overflowed
1382 // here which will cause a2 to become negative. 1401 // here which will cause a2 to become negative.
1383 __ subu(a2, sp, a2); 1402 __ subu(a2, sp, a2);
1384 // Check if the arguments will overflow the stack. 1403 // Check if the arguments will overflow the stack.
1385 __ sll(t0, v0, kPointerSizeLog2 - kSmiTagSize); 1404 __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize);
1386 __ Branch(&okay, gt, a2, Operand(t0)); // Signed comparison. 1405 __ Branch(&okay, gt, a2, Operand(t3)); // Signed comparison.
1387 1406
1388 // Out of stack space. 1407 // Out of stack space.
1389 __ lw(a1, MemOperand(fp, kFunctionOffset)); 1408 __ lw(a1, MemOperand(fp, kFunctionOffset));
1390 __ push(a1); 1409 __ push(a1);
1391 __ push(v0); 1410 __ push(v0);
1392 __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION); 1411 __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
1393 // End of stack check. 1412 // End of stack check.
1394 1413
1395 // Push current limit and index. 1414 // Push current limit and index.
1396 __ bind(&okay); 1415 __ bind(&okay);
1397 __ push(v0); // Limit. 1416 __ push(v0); // Limit.
1398 __ mov(a1, zero_reg); // Initial index. 1417 __ mov(a1, zero_reg); // Initial index.
1399 __ push(a1); 1418 __ push(a1);
1400 1419
1420 // Get the receiver.
1421 __ lw(a0, MemOperand(fp, kRecvOffset));
1422
1423 // Check that the function is a JS function (otherwise it must be a proxy).
1424 Label push_receiver;
1425 __ lw(a1, MemOperand(fp, kFunctionOffset));
1426 __ GetObjectType(a1, a2, a2);
1427 __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE));
1428
1401 // Change context eagerly to get the right global object if necessary. 1429 // Change context eagerly to get the right global object if necessary.
1402 __ lw(a0, MemOperand(fp, kFunctionOffset)); 1430 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1403 __ lw(cp, FieldMemOperand(a0, JSFunction::kContextOffset)); 1431 // Load the shared function info while the function is still in a1.
1404 // Load the shared function info while the function is still in a0. 1432 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1405 __ lw(a1, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset));
1406 1433
1407 // Compute the receiver. 1434 // Compute the receiver.
1408 Label call_to_object, use_global_receiver, push_receiver;
1409 __ lw(a0, MemOperand(fp, kRecvOffset));
1410
1411 // Do not transform the receiver for strict mode functions. 1435 // Do not transform the receiver for strict mode functions.
1412 __ lw(a2, FieldMemOperand(a1, SharedFunctionInfo::kCompilerHintsOffset)); 1436 Label call_to_object, use_global_receiver;
1413 __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 1437 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
1438 __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1414 kSmiTagSize))); 1439 kSmiTagSize)));
1415 __ Branch(&push_receiver, ne, t0, Operand(zero_reg)); 1440 __ Branch(&push_receiver, ne, t3, Operand(zero_reg));
1416 1441
1417 // Do not transform the receiver for native (Compilerhints already in a2). 1442 // Do not transform the receiver for native (Compilerhints already in a2).
1418 __ And(t0, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 1443 __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1419 __ Branch(&push_receiver, ne, t0, Operand(zero_reg)); 1444 __ Branch(&push_receiver, ne, t3, Operand(zero_reg));
1420 1445
1421 // Compute the receiver in non-strict mode. 1446 // Compute the receiver in non-strict mode.
1422 __ And(t0, a0, Operand(kSmiTagMask)); 1447 __ And(t3, a0, Operand(kSmiTagMask));
1423 __ Branch(&call_to_object, eq, t0, Operand(zero_reg)); 1448 __ Branch(&call_to_object, eq, t3, Operand(zero_reg));
1424 __ LoadRoot(a1, Heap::kNullValueRootIndex); 1449 __ LoadRoot(a1, Heap::kNullValueRootIndex);
1425 __ Branch(&use_global_receiver, eq, a0, Operand(a1)); 1450 __ Branch(&use_global_receiver, eq, a0, Operand(a1));
1426 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 1451 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1427 __ Branch(&use_global_receiver, eq, a0, Operand(a2)); 1452 __ Branch(&use_global_receiver, eq, a0, Operand(a2));
1428 1453
1429 // Check if the receiver is already a JavaScript object. 1454 // Check if the receiver is already a JavaScript object.
1430 // a0: receiver 1455 // a0: receiver
1431 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 1456 STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1432 __ GetObjectType(a0, a1, a1); 1457 __ GetObjectType(a0, a1, a1);
1433 __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); 1458 __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 // Use inline caching to access the arguments. 1499 // Use inline caching to access the arguments.
1475 __ lw(a0, MemOperand(fp, kIndexOffset)); 1500 __ lw(a0, MemOperand(fp, kIndexOffset));
1476 __ Addu(a0, a0, Operand(1 << kSmiTagSize)); 1501 __ Addu(a0, a0, Operand(1 << kSmiTagSize));
1477 __ sw(a0, MemOperand(fp, kIndexOffset)); 1502 __ sw(a0, MemOperand(fp, kIndexOffset));
1478 1503
1479 // Test if the copy loop has finished copying all the elements from the 1504 // Test if the copy loop has finished copying all the elements from the
1480 // arguments object. 1505 // arguments object.
1481 __ bind(&entry); 1506 __ bind(&entry);
1482 __ lw(a1, MemOperand(fp, kLimitOffset)); 1507 __ lw(a1, MemOperand(fp, kLimitOffset));
1483 __ Branch(&loop, ne, a0, Operand(a1)); 1508 __ Branch(&loop, ne, a0, Operand(a1));
1509
1484 // Invoke the function. 1510 // Invoke the function.
1511 Label call_proxy;
1485 ParameterCount actual(a0); 1512 ParameterCount actual(a0);
1486 __ sra(a0, a0, kSmiTagSize); 1513 __ sra(a0, a0, kSmiTagSize);
1487 __ lw(a1, MemOperand(fp, kFunctionOffset)); 1514 __ lw(a1, MemOperand(fp, kFunctionOffset));
1515 __ GetObjectType(a1, a2, a2);
1516 __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE));
1517
1488 __ InvokeFunction(a1, actual, CALL_FUNCTION, 1518 __ InvokeFunction(a1, actual, CALL_FUNCTION,
1489 NullCallWrapper(), CALL_AS_METHOD); 1519 NullCallWrapper(), CALL_AS_METHOD);
1490 1520
1521 frame_scope.GenerateLeaveFrame();
1522 __ Ret(USE_DELAY_SLOT);
1523 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot.
1524
1525 // Invoke the function proxy.
1526 __ bind(&call_proxy);
1527 __ push(a1); // Add function proxy as last argument.
1528 __ Addu(a0, a0, Operand(1));
1529 __ li(a2, Operand(0, RelocInfo::NONE));
1530 __ SetCallKind(t1, CALL_AS_METHOD);
1531 __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
1532 __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1533 RelocInfo::CODE_TARGET);
1534
1491 // Tear down the internal frame and remove function, receiver and args. 1535 // Tear down the internal frame and remove function, receiver and args.
1492 } 1536 }
1493 __ Addu(sp, sp, Operand(3 * kPointerSize)); 1537
1494 __ Ret(); 1538 __ Ret(USE_DELAY_SLOT);
1539 __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot.
1495 } 1540 }
1496 1541
1497 1542
1498 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1543 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1499 __ sll(a0, a0, kSmiTagSize); 1544 __ sll(a0, a0, kSmiTagSize);
1500 __ li(t0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1545 __ li(t0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1501 __ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit()); 1546 __ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit());
1502 __ Addu(fp, sp, Operand(3 * kPointerSize)); 1547 __ Addu(fp, sp, Operand(3 * kPointerSize));
1503 } 1548 }
1504 1549
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1632 __ bind(&dont_adapt_arguments); 1677 __ bind(&dont_adapt_arguments);
1633 __ Jump(a3); 1678 __ Jump(a3);
1634 } 1679 }
1635 1680
1636 1681
1637 #undef __ 1682 #undef __
1638 1683
1639 } } // namespace v8::internal 1684 } } // namespace v8::internal
1640 1685
1641 #endif // V8_TARGET_ARCH_MIPS 1686 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698