| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 // Clobber all input registers when running with the debug-code flag | 176 // Clobber all input registers when running with the debug-code flag |
| 177 // turned on to provoke errors. | 177 // turned on to provoke errors. |
| 178 if (FLAG_debug_code) { | 178 if (FLAG_debug_code) { |
| 179 mov(object, Immediate(BitCast<int32_t>(kZapValue))); | 179 mov(object, Immediate(BitCast<int32_t>(kZapValue))); |
| 180 mov(address, Immediate(BitCast<int32_t>(kZapValue))); | 180 mov(address, Immediate(BitCast<int32_t>(kZapValue))); |
| 181 mov(value, Immediate(BitCast<int32_t>(kZapValue))); | 181 mov(value, Immediate(BitCast<int32_t>(kZapValue))); |
| 182 } | 182 } |
| 183 } | 183 } |
| 184 | 184 |
| 185 | 185 |
| 186 void MacroAssembler::StackLimitCheck(Label* on_stack_overflow) { | |
| 187 cmp(esp, | |
| 188 Operand::StaticVariable(ExternalReference::address_of_stack_limit())); | |
| 189 j(below, on_stack_overflow); | |
| 190 } | |
| 191 | |
| 192 | |
| 193 #ifdef ENABLE_DEBUGGER_SUPPORT | 186 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 194 void MacroAssembler::DebugBreak() { | 187 void MacroAssembler::DebugBreak() { |
| 195 Set(eax, Immediate(0)); | 188 Set(eax, Immediate(0)); |
| 196 mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak))); | 189 mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak))); |
| 197 CEntryStub ces(1); | 190 CEntryStub ces(1); |
| 198 call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 191 call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
| 199 } | 192 } |
| 200 #endif | 193 #endif |
| 201 | 194 |
| 202 | 195 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. | 350 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. |
| 358 | 351 |
| 359 // Save the frame pointer and the context in top. | 352 // Save the frame pointer and the context in top. |
| 360 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address); | 353 ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address); |
| 361 ExternalReference context_address(Isolate::k_context_address); | 354 ExternalReference context_address(Isolate::k_context_address); |
| 362 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 355 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
| 363 mov(Operand::StaticVariable(context_address), esi); | 356 mov(Operand::StaticVariable(context_address), esi); |
| 364 } | 357 } |
| 365 | 358 |
| 366 | 359 |
| 367 void MacroAssembler::EnterExitFrameEpilogue(int argc) { | 360 void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { |
| 368 // Reserve space for arguments. | 361 // Optionally save all XMM registers. |
| 369 sub(Operand(esp), Immediate(argc * kPointerSize)); | 362 if (save_doubles) { |
| 363 CpuFeatures::Scope scope(SSE2); |
| 364 int space = XMMRegister::kNumRegisters * kDoubleSize + argc * kPointerSize; |
| 365 sub(Operand(esp), Immediate(space)); |
| 366 int offset = -2 * kPointerSize; |
| 367 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { |
| 368 XMMRegister reg = XMMRegister::from_code(i); |
| 369 movdbl(Operand(ebp, offset - ((i + 1) * kDoubleSize)), reg); |
| 370 } |
| 371 } else { |
| 372 sub(Operand(esp), Immediate(argc * kPointerSize)); |
| 373 } |
| 370 | 374 |
| 371 // Get the required frame alignment for the OS. | 375 // Get the required frame alignment for the OS. |
| 372 const int kFrameAlignment = OS::ActivationFrameAlignment(); | 376 const int kFrameAlignment = OS::ActivationFrameAlignment(); |
| 373 if (kFrameAlignment > 0) { | 377 if (kFrameAlignment > 0) { |
| 374 ASSERT(IsPowerOf2(kFrameAlignment)); | 378 ASSERT(IsPowerOf2(kFrameAlignment)); |
| 375 and_(esp, -kFrameAlignment); | 379 and_(esp, -kFrameAlignment); |
| 376 } | 380 } |
| 377 | 381 |
| 378 // Patch the saved entry sp. | 382 // Patch the saved entry sp. |
| 379 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); | 383 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); |
| 380 } | 384 } |
| 381 | 385 |
| 382 | 386 |
| 383 void MacroAssembler::EnterExitFrame() { | 387 void MacroAssembler::EnterExitFrame(bool save_doubles) { |
| 384 EnterExitFramePrologue(); | 388 EnterExitFramePrologue(); |
| 385 | 389 |
| 386 // Setup argc and argv in callee-saved registers. | 390 // Setup argc and argv in callee-saved registers. |
| 387 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 391 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
| 388 mov(edi, Operand(eax)); | 392 mov(edi, Operand(eax)); |
| 389 lea(esi, Operand(ebp, eax, times_4, offset)); | 393 lea(esi, Operand(ebp, eax, times_4, offset)); |
| 390 | 394 |
| 391 // Reserve space for argc, argv and isolate. | 395 // Reserve space for argc, argv and isolate. |
| 392 EnterExitFrameEpilogue(3); | 396 EnterExitFrameEpilogue(3, save_doubles); |
| 393 } | 397 } |
| 394 | 398 |
| 395 | 399 |
| 396 void MacroAssembler::EnterApiExitFrame(int argc) { | 400 void MacroAssembler::EnterApiExitFrame(int argc) { |
| 397 EnterExitFramePrologue(); | 401 EnterExitFramePrologue(); |
| 398 EnterExitFrameEpilogue(argc); | 402 EnterExitFrameEpilogue(argc, false); |
| 399 } | 403 } |
| 400 | 404 |
| 401 | 405 |
| 402 void MacroAssembler::LeaveExitFrame() { | 406 void MacroAssembler::LeaveExitFrame(bool save_doubles) { |
| 407 // Optionally restore all XMM registers. |
| 408 if (save_doubles) { |
| 409 CpuFeatures::Scope scope(SSE2); |
| 410 int offset = -2 * kPointerSize; |
| 411 for (int i = 0; i < XMMRegister::kNumRegisters; i++) { |
| 412 XMMRegister reg = XMMRegister::from_code(i); |
| 413 movdbl(reg, Operand(ebp, offset - ((i + 1) * kDoubleSize))); |
| 414 } |
| 415 } |
| 416 |
| 403 // Get the return address from the stack and restore the frame pointer. | 417 // Get the return address from the stack and restore the frame pointer. |
| 404 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 418 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
| 405 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 419 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
| 406 | 420 |
| 407 // Pop the arguments and the receiver from the caller stack. | 421 // Pop the arguments and the receiver from the caller stack. |
| 408 lea(esp, Operand(esi, 1 * kPointerSize)); | 422 lea(esp, Operand(esi, 1 * kPointerSize)); |
| 409 | 423 |
| 410 // Push the return address to get ready to return. | 424 // Push the return address to get ready to return. |
| 411 push(ecx); | 425 push(ecx); |
| 412 | 426 |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1093 mov(index, hash); | 1107 mov(index, hash); |
| 1094 } | 1108 } |
| 1095 } | 1109 } |
| 1096 | 1110 |
| 1097 | 1111 |
| 1098 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { | 1112 void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) { |
| 1099 CallRuntime(Runtime::FunctionForId(id), num_arguments); | 1113 CallRuntime(Runtime::FunctionForId(id), num_arguments); |
| 1100 } | 1114 } |
| 1101 | 1115 |
| 1102 | 1116 |
| 1117 void MacroAssembler::CallRuntimeSaveDoubles(Runtime::FunctionId id) { |
| 1118 const Runtime::Function* function = Runtime::FunctionForId(id); |
| 1119 Set(eax, Immediate(function->nargs)); |
| 1120 mov(ebx, Immediate(ExternalReference(function))); |
| 1121 CEntryStub ces(1); |
| 1122 ces.SaveDoubles(); |
| 1123 CallStub(&ces); |
| 1124 } |
| 1125 |
| 1126 |
| 1103 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, | 1127 MaybeObject* MacroAssembler::TryCallRuntime(Runtime::FunctionId id, |
| 1104 int num_arguments) { | 1128 int num_arguments) { |
| 1105 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); | 1129 return TryCallRuntime(Runtime::FunctionForId(id), num_arguments); |
| 1106 } | 1130 } |
| 1107 | 1131 |
| 1108 | 1132 |
| 1109 void MacroAssembler::CallRuntime(const Runtime::Function* f, | 1133 void MacroAssembler::CallRuntime(const Runtime::Function* f, |
| 1110 int num_arguments) { | 1134 int num_arguments) { |
| 1111 // If the expected number of arguments of the runtime function is | 1135 // If the expected number of arguments of the runtime function is |
| 1112 // constant, we check that the actual number of arguments match the | 1136 // constant, we check that the actual number of arguments match the |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 CEntryStub ces(1); | 1357 CEntryStub ces(1); |
| 1334 return TryTailCallStub(&ces); | 1358 return TryTailCallStub(&ces); |
| 1335 } | 1359 } |
| 1336 | 1360 |
| 1337 | 1361 |
| 1338 void MacroAssembler::InvokePrologue(const ParameterCount& expected, | 1362 void MacroAssembler::InvokePrologue(const ParameterCount& expected, |
| 1339 const ParameterCount& actual, | 1363 const ParameterCount& actual, |
| 1340 Handle<Code> code_constant, | 1364 Handle<Code> code_constant, |
| 1341 const Operand& code_operand, | 1365 const Operand& code_operand, |
| 1342 Label* done, | 1366 Label* done, |
| 1343 InvokeFlag flag) { | 1367 InvokeFlag flag, |
| 1368 PostCallGenerator* post_call_generator) { |
| 1344 bool definitely_matches = false; | 1369 bool definitely_matches = false; |
| 1345 Label invoke; | 1370 Label invoke; |
| 1346 if (expected.is_immediate()) { | 1371 if (expected.is_immediate()) { |
| 1347 ASSERT(actual.is_immediate()); | 1372 ASSERT(actual.is_immediate()); |
| 1348 if (expected.immediate() == actual.immediate()) { | 1373 if (expected.immediate() == actual.immediate()) { |
| 1349 definitely_matches = true; | 1374 definitely_matches = true; |
| 1350 } else { | 1375 } else { |
| 1351 mov(eax, actual.immediate()); | 1376 mov(eax, actual.immediate()); |
| 1352 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 1377 const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 1353 if (expected.immediate() == sentinel) { | 1378 if (expected.immediate() == sentinel) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1385 Builtins::ArgumentsAdaptorTrampoline)); | 1410 Builtins::ArgumentsAdaptorTrampoline)); |
| 1386 if (!code_constant.is_null()) { | 1411 if (!code_constant.is_null()) { |
| 1387 mov(edx, Immediate(code_constant)); | 1412 mov(edx, Immediate(code_constant)); |
| 1388 add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); | 1413 add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag)); |
| 1389 } else if (!code_operand.is_reg(edx)) { | 1414 } else if (!code_operand.is_reg(edx)) { |
| 1390 mov(edx, code_operand); | 1415 mov(edx, code_operand); |
| 1391 } | 1416 } |
| 1392 | 1417 |
| 1393 if (flag == CALL_FUNCTION) { | 1418 if (flag == CALL_FUNCTION) { |
| 1394 call(adaptor, RelocInfo::CODE_TARGET); | 1419 call(adaptor, RelocInfo::CODE_TARGET); |
| 1420 if (post_call_generator != NULL) post_call_generator->Generate(); |
| 1395 jmp(done); | 1421 jmp(done); |
| 1396 } else { | 1422 } else { |
| 1397 jmp(adaptor, RelocInfo::CODE_TARGET); | 1423 jmp(adaptor, RelocInfo::CODE_TARGET); |
| 1398 } | 1424 } |
| 1399 bind(&invoke); | 1425 bind(&invoke); |
| 1400 } | 1426 } |
| 1401 } | 1427 } |
| 1402 | 1428 |
| 1403 | 1429 |
| 1404 void MacroAssembler::InvokeCode(const Operand& code, | 1430 void MacroAssembler::InvokeCode(const Operand& code, |
| 1405 const ParameterCount& expected, | 1431 const ParameterCount& expected, |
| 1406 const ParameterCount& actual, | 1432 const ParameterCount& actual, |
| 1407 InvokeFlag flag) { | 1433 InvokeFlag flag, |
| 1434 PostCallGenerator* post_call_generator) { |
| 1408 Label done; | 1435 Label done; |
| 1409 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag); | 1436 InvokePrologue(expected, actual, Handle<Code>::null(), code, |
| 1437 &done, flag, post_call_generator); |
| 1410 if (flag == CALL_FUNCTION) { | 1438 if (flag == CALL_FUNCTION) { |
| 1411 call(code); | 1439 call(code); |
| 1440 if (post_call_generator != NULL) post_call_generator->Generate(); |
| 1412 } else { | 1441 } else { |
| 1413 ASSERT(flag == JUMP_FUNCTION); | 1442 ASSERT(flag == JUMP_FUNCTION); |
| 1414 jmp(code); | 1443 jmp(code); |
| 1415 } | 1444 } |
| 1416 bind(&done); | 1445 bind(&done); |
| 1417 } | 1446 } |
| 1418 | 1447 |
| 1419 | 1448 |
| 1420 void MacroAssembler::InvokeCode(Handle<Code> code, | 1449 void MacroAssembler::InvokeCode(Handle<Code> code, |
| 1421 const ParameterCount& expected, | 1450 const ParameterCount& expected, |
| 1422 const ParameterCount& actual, | 1451 const ParameterCount& actual, |
| 1423 RelocInfo::Mode rmode, | 1452 RelocInfo::Mode rmode, |
| 1424 InvokeFlag flag) { | 1453 InvokeFlag flag, |
| 1454 PostCallGenerator* post_call_generator) { |
| 1425 Label done; | 1455 Label done; |
| 1426 Operand dummy(eax); | 1456 Operand dummy(eax); |
| 1427 InvokePrologue(expected, actual, code, dummy, &done, flag); | 1457 InvokePrologue(expected, actual, code, dummy, &done, |
| 1458 flag, post_call_generator); |
| 1428 if (flag == CALL_FUNCTION) { | 1459 if (flag == CALL_FUNCTION) { |
| 1429 call(code, rmode); | 1460 call(code, rmode); |
| 1461 if (post_call_generator != NULL) post_call_generator->Generate(); |
| 1430 } else { | 1462 } else { |
| 1431 ASSERT(flag == JUMP_FUNCTION); | 1463 ASSERT(flag == JUMP_FUNCTION); |
| 1432 jmp(code, rmode); | 1464 jmp(code, rmode); |
| 1433 } | 1465 } |
| 1434 bind(&done); | 1466 bind(&done); |
| 1435 } | 1467 } |
| 1436 | 1468 |
| 1437 | 1469 |
| 1438 void MacroAssembler::InvokeFunction(Register fun, | 1470 void MacroAssembler::InvokeFunction(Register fun, |
| 1439 const ParameterCount& actual, | 1471 const ParameterCount& actual, |
| 1440 InvokeFlag flag) { | 1472 InvokeFlag flag, |
| 1473 PostCallGenerator* post_call_generator) { |
| 1441 ASSERT(fun.is(edi)); | 1474 ASSERT(fun.is(edi)); |
| 1442 mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 1475 mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
| 1443 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 1476 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 1444 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 1477 mov(ebx, FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1445 SmiUntag(ebx); | 1478 SmiUntag(ebx); |
| 1446 | 1479 |
| 1447 ParameterCount expected(ebx); | 1480 ParameterCount expected(ebx); |
| 1448 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 1481 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
| 1449 expected, actual, flag); | 1482 expected, actual, flag, post_call_generator); |
| 1450 } | 1483 } |
| 1451 | 1484 |
| 1452 | 1485 |
| 1453 void MacroAssembler::InvokeFunction(JSFunction* function, | 1486 void MacroAssembler::InvokeFunction(JSFunction* function, |
| 1454 const ParameterCount& actual, | 1487 const ParameterCount& actual, |
| 1455 InvokeFlag flag) { | 1488 InvokeFlag flag, |
| 1489 PostCallGenerator* post_call_generator) { |
| 1456 ASSERT(function->is_compiled()); | 1490 ASSERT(function->is_compiled()); |
| 1457 // Get the function and setup the context. | 1491 // Get the function and setup the context. |
| 1458 mov(edi, Immediate(Handle<JSFunction>(function))); | 1492 mov(edi, Immediate(Handle<JSFunction>(function))); |
| 1459 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 1493 mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
| 1460 // Invoke the cached code. | 1494 |
| 1461 Handle<Code> code(function->code()); | |
| 1462 ParameterCount expected(function->shared()->formal_parameter_count()); | 1495 ParameterCount expected(function->shared()->formal_parameter_count()); |
| 1463 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); | 1496 if (V8::UseCrankshaft()) { |
| 1497 // TODO(kasperl): For now, we always call indirectly through the |
| 1498 // code field in the function to allow recompilation to take effect |
| 1499 // without changing any of the call sites. |
| 1500 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
| 1501 expected, actual, flag, post_call_generator); |
| 1502 } else { |
| 1503 Handle<Code> code(function->code()); |
| 1504 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, |
| 1505 flag, post_call_generator); |
| 1506 } |
| 1464 } | 1507 } |
| 1465 | 1508 |
| 1466 | 1509 |
| 1467 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { | 1510 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
| 1511 InvokeFlag flag, |
| 1512 PostCallGenerator* post_call_generator) { |
| 1468 // Calls are not allowed in some stubs. | 1513 // Calls are not allowed in some stubs. |
| 1469 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); | 1514 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); |
| 1470 | 1515 |
| 1471 // Rely on the assertion to check that the number of provided | 1516 // Rely on the assertion to check that the number of provided |
| 1472 // arguments match the expected number of arguments. Fake a | 1517 // arguments match the expected number of arguments. Fake a |
| 1473 // parameter count to avoid emitting code to do the check. | 1518 // parameter count to avoid emitting code to do the check. |
| 1474 ParameterCount expected(0); | 1519 ParameterCount expected(0); |
| 1475 GetBuiltinFunction(edi, id); | 1520 GetBuiltinFunction(edi, id); |
| 1476 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), | 1521 InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), |
| 1477 expected, expected, flag); | 1522 expected, expected, flag, post_call_generator); |
| 1478 } | 1523 } |
| 1479 | 1524 |
| 1480 void MacroAssembler::GetBuiltinFunction(Register target, | 1525 void MacroAssembler::GetBuiltinFunction(Register target, |
| 1481 Builtins::JavaScript id) { | 1526 Builtins::JavaScript id) { |
| 1482 // Load the JavaScript builtin function from the builtins object. | 1527 // Load the JavaScript builtin function from the builtins object. |
| 1483 mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 1528 mov(target, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
| 1484 mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); | 1529 mov(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); |
| 1485 mov(target, FieldOperand(target, | 1530 mov(target, FieldOperand(target, |
| 1486 JSBuiltinsObject::OffsetOfFunctionWithId(id))); | 1531 JSBuiltinsObject::OffsetOfFunctionWithId(id))); |
| 1487 } | 1532 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1532 Label ok, fail; | 1577 Label ok, fail; |
| 1533 CheckMap(map, FACTORY->meta_map(), &fail, false); | 1578 CheckMap(map, FACTORY->meta_map(), &fail, false); |
| 1534 jmp(&ok); | 1579 jmp(&ok); |
| 1535 bind(&fail); | 1580 bind(&fail); |
| 1536 Abort("Global functions must have initial map"); | 1581 Abort("Global functions must have initial map"); |
| 1537 bind(&ok); | 1582 bind(&ok); |
| 1538 } | 1583 } |
| 1539 } | 1584 } |
| 1540 | 1585 |
| 1541 | 1586 |
| 1587 int MacroAssembler::SafepointRegisterStackIndex(int reg_code) { |
| 1588 // The registers are pushed starting with the lowest encoding, |
| 1589 // which means that lowest encodings are furthest away from |
| 1590 // the stack pointer. |
| 1591 ASSERT(reg_code >= 0 && reg_code < kNumSafepointRegisters); |
| 1592 return kNumSafepointRegisters - reg_code - 1; |
| 1593 } |
| 1594 |
| 1595 |
| 1542 void MacroAssembler::Ret() { | 1596 void MacroAssembler::Ret() { |
| 1543 ret(0); | 1597 ret(0); |
| 1544 } | 1598 } |
| 1545 | 1599 |
| 1546 | 1600 |
| 1547 void MacroAssembler::Drop(int stack_elements) { | 1601 void MacroAssembler::Drop(int stack_elements) { |
| 1548 if (stack_elements > 0) { | 1602 if (stack_elements > 0) { |
| 1549 add(Operand(esp), Immediate(stack_elements * kPointerSize)); | 1603 add(Operand(esp), Immediate(stack_elements * kPointerSize)); |
| 1550 } | 1604 } |
| 1551 } | 1605 } |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 | 1924 |
| 1871 // Check that the code was patched as expected. | 1925 // Check that the code was patched as expected. |
| 1872 ASSERT(masm_.pc_ == address_ + size_); | 1926 ASSERT(masm_.pc_ == address_ + size_); |
| 1873 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 1927 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 1874 } | 1928 } |
| 1875 | 1929 |
| 1876 | 1930 |
| 1877 } } // namespace v8::internal | 1931 } } // namespace v8::internal |
| 1878 | 1932 |
| 1879 #endif // V8_TARGET_ARCH_IA32 | 1933 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |