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

Side by Side Diff: third_party/WebKit/JavaScriptCore/VM/CTI.cpp

Issue 10670: Do another merge using nifty new merge script (CL for that coming soon). (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 void CTI::compileOpCallInitializeCallFrame(unsigned, unsigned argCount) 580 void CTI::compileOpCallInitializeCallFrame(unsigned, unsigned argCount)
581 { 581 {
582 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeC hain, m_node), X86::ecx, X86::ebx); // newScopeChain 582 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeC hain, m_node), X86::ecx, X86::ebx); // newScopeChain
583 583
584 m_jit.movl_i32m(asInteger(noValue()), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edi); 584 m_jit.movl_i32m(asInteger(noValue()), RegisterFile::OptionalCalleeArguments * static_cast<int>(sizeof(Register)), X86::edi);
585 m_jit.movl_rm(X86::ecx, RegisterFile::Callee * static_cast<int>(sizeof(Regis ter)), X86::edi); 585 m_jit.movl_rm(X86::ecx, RegisterFile::Callee * static_cast<int>(sizeof(Regis ter)), X86::edi);
586 m_jit.movl_i32m(argCount, RegisterFile::ArgumentCount * static_cast<int>(siz eof(Register)), X86::edi); 586 m_jit.movl_i32m(argCount, RegisterFile::ArgumentCount * static_cast<int>(siz eof(Register)), X86::edi);
587 m_jit.movl_rm(X86::ebx, RegisterFile::ScopeChain * static_cast<int>(sizeof(R egister)), X86::edi); 587 m_jit.movl_rm(X86::ebx, RegisterFile::ScopeChain * static_cast<int>(sizeof(R egister)), X86::edi);
588 } 588 }
589 589
590 void CTI::compileOpCallSetupArgs(Instruction* instruction, bool isConstruct, boo l isEval) 590 void CTI::compileOpCallSetupArgs(Instruction* instruction)
591 { 591 {
592 int firstArg = instruction[4].u.operand; 592 int argCount = instruction[3].u.operand;
593 int argCount = instruction[5].u.operand; 593 int registerOffset = instruction[4].u.operand;
594 int registerOffset = instruction[6].u.operand;
595 594
595 // ecx holds func
596 emitPutArg(X86::ecx, 0); 596 emitPutArg(X86::ecx, 0);
597 emitPutArgConstant(registerOffset, 4); 597 emitPutArgConstant(registerOffset, 4);
598 emitPutArgConstant(argCount, 8); 598 emitPutArgConstant(argCount, 8);
599 emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 12); 599 emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 12);
600 if (isConstruct) { 600 }
601 emitGetPutArg(instruction[3].u.operand, 16, X86::eax); 601
602 emitPutArgConstant(firstArg, 20); 602 void CTI::compileOpCallEvalSetupArgs(Instruction* instruction)
603 } else if (isEval) 603 {
604 emitGetPutArg(instruction[3].u.operand, 16, X86::eax); 604 int argCount = instruction[3].u.operand;
605 int registerOffset = instruction[4].u.operand;
606
607 // ecx holds func
608 emitPutArg(X86::ecx, 0);
609 emitPutArgConstant(registerOffset, 4);
610 emitPutArgConstant(argCount, 8);
611 emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 12);
612 }
613
614 void CTI::compileOpConstructSetupArgs(Instruction* instruction)
615 {
616 int argCount = instruction[3].u.operand;
617 int registerOffset = instruction[4].u.operand;
618 int proto = instruction[5].u.operand;
619 int thisRegister = instruction[6].u.operand;
620
621 // ecx holds func
622 emitPutArg(X86::ecx, 0);
623 emitPutArgConstant(registerOffset, 4);
624 emitPutArgConstant(argCount, 8);
625 emitGetPutArg(proto, 12, X86::eax);
626 emitPutArgConstant(thisRegister, 16);
627 emitPutArgConstant(reinterpret_cast<unsigned>(instruction), 20);
605 } 628 }
606 629
607 void CTI::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex) 630 void CTI::compileOpCall(OpcodeID opcodeID, Instruction* instruction, unsigned i, unsigned callLinkInfoIndex)
608 { 631 {
609 int dst = instruction[1].u.operand; 632 int dst = instruction[1].u.operand;
610 int callee = instruction[2].u.operand; 633 int callee = instruction[2].u.operand;
611 int firstArg = instruction[4].u.operand; 634 int argCount = instruction[3].u.operand;
612 int argCount = instruction[5].u.operand; 635 int registerOffset = instruction[4].u.operand;
613 int registerOffset = instruction[6].u.operand;
614
615 // Setup this value as the first argument (does not apply to constructors)
616 if (opcodeID != op_construct) {
617 int thisVal = instruction[3].u.operand;
618 if (thisVal == missingThisObjectMarker())
619 m_jit.movl_i32m(asInteger(jsNull()), firstArg * sizeof(Register), X8 6::edi);
620 else {
621 emitGetArg(thisVal, X86::eax);
622 emitPutResult(firstArg);
623 }
624 }
625 636
626 // Handle eval 637 // Handle eval
627 X86Assembler::JmpSrc wasEval; 638 X86Assembler::JmpSrc wasEval;
628 if (opcodeID == op_call_eval) { 639 if (opcodeID == op_call_eval) {
629 emitGetArg(callee, X86::ecx); 640 emitGetArg(callee, X86::ecx);
630 compileOpCallSetupArgs(instruction, false, true); 641 compileOpCallEvalSetupArgs(instruction);
631 642
632 emitCTICall(instruction, i, Machine::cti_op_call_eval); 643 emitCTICall(instruction, i, Machine::cti_op_call_eval);
633 m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::eax); 644 m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::eax);
634 wasEval = m_jit.emitUnlinkedJne(); 645 wasEval = m_jit.emitUnlinkedJne();
635 } 646 }
636 647
637 // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee. 648 // This plants a check for a cached JSFunction value, so we can plant a fast link to the callee.
638 // This deliberately leaves the callee in ecx, used when setting up the stac k frame below 649 // This deliberately leaves the callee in ecx, used when setting up the stac k frame below
639 emitGetArg(callee, X86::ecx); 650 emitGetArg(callee, X86::ecx);
640 m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::ecx); 651 m_jit.cmpl_i32r(asInteger(JSImmediate::impossibleValue()), X86::ecx);
641 X86Assembler::JmpDst addressOfLinkedFunctionCheck = m_jit.label(); 652 X86Assembler::JmpDst addressOfLinkedFunctionCheck = m_jit.label();
642 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i)); 653 m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJne(), i));
643 ASSERT(X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck , m_jit.label()) == repatchOffsetOpCallCall); 654 ASSERT(X86Assembler::getDifferenceBetweenLabels(addressOfLinkedFunctionCheck , m_jit.label()) == repatchOffsetOpCallCall);
644 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = address OfLinkedFunctionCheck; 655 m_callStructureStubCompilationInfo[callLinkInfoIndex].hotPathBegin = address OfLinkedFunctionCheck;
645 656
646 // The following is the fast case, only used whan a callee can be linked. 657 // The following is the fast case, only used whan a callee can be linked.
647 658
648 // In the case of OpConstruct, call out to a cti_ function to create the new object. 659 // In the case of OpConstruct, call out to a cti_ function to create the new object.
649 if (opcodeID == op_construct) { 660 if (opcodeID == op_construct) {
661 int proto = instruction[5].u.operand;
662 int thisRegister = instruction[6].u.operand;
663
650 emitPutArg(X86::ecx, 0); 664 emitPutArg(X86::ecx, 0);
651 emitGetPutArg(instruction[3].u.operand, 16, X86::eax); 665 emitGetPutArg(proto, 12, X86::eax);
652 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruct); 666 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruct);
653 emitPutResult(firstArg); 667 emitPutResult(thisRegister);
654 emitGetArg(callee, X86::ecx); 668 emitGetArg(callee, X86::ecx);
655 } 669 }
656 670
657 // Fast version of stack frame initialization, directly relative to edi. 671 // Fast version of stack frame initialization, directly relative to edi.
658 // Note that this omits to set up RegisterFile::CodeBlock, which is set in t he callee 672 // Note that this omits to set up RegisterFile::CodeBlock, which is set in t he callee
659 m_jit.movl_i32m(asInteger(noValue()), (registerOffset + RegisterFile::Option alCalleeArguments) * static_cast<int>(sizeof(Register)), X86::edi); 673 m_jit.movl_i32m(asInteger(noValue()), (registerOffset + RegisterFile::Option alCalleeArguments) * static_cast<int>(sizeof(Register)), X86::edi);
660 m_jit.movl_rm(X86::ecx, (registerOffset + RegisterFile::Callee) * static_cas t<int>(sizeof(Register)), X86::edi); 674 m_jit.movl_rm(X86::ecx, (registerOffset + RegisterFile::Callee) * static_cas t<int>(sizeof(Register)), X86::edi);
661 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeC hain, m_node), X86::ecx, X86::edx); // newScopeChain 675 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_scopeChain) + OBJECT_OFFSET(ScopeC hain, m_node), X86::ecx, X86::edx); // newScopeChain
662 m_jit.movl_i32m(argCount, (registerOffset + RegisterFile::ArgumentCount) * s tatic_cast<int>(sizeof(Register)), X86::edi); 676 m_jit.movl_i32m(argCount, (registerOffset + RegisterFile::ArgumentCount) * s tatic_cast<int>(sizeof(Register)), X86::edi);
663 m_jit.movl_rm(X86::edi, (registerOffset + RegisterFile::CallerFrame) * stati c_cast<int>(sizeof(Register)), X86::edi); 677 m_jit.movl_rm(X86::edi, (registerOffset + RegisterFile::CallerFrame) * stati c_cast<int>(sizeof(Register)), X86::edi);
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
1278 break; 1292 break;
1279 } 1293 }
1280 case op_new_func: { 1294 case op_new_func: {
1281 FuncDeclNode* func = (m_codeBlock->functions[instruction[i + 2].u.op erand]).get(); 1295 FuncDeclNode* func = (m_codeBlock->functions[instruction[i + 2].u.op erand]).get();
1282 emitPutArgConstant(reinterpret_cast<unsigned>(func), 0); 1296 emitPutArgConstant(reinterpret_cast<unsigned>(func), 0);
1283 emitCTICall(instruction + i, i, Machine::cti_op_new_func); 1297 emitCTICall(instruction + i, i, Machine::cti_op_new_func);
1284 emitPutResult(instruction[i + 1].u.operand); 1298 emitPutResult(instruction[i + 1].u.operand);
1285 i += 3; 1299 i += 3;
1286 break; 1300 break;
1287 } 1301 }
1288 case op_call: { 1302 case op_call:
1303 case op_call_eval:
1304 case op_construct: {
1289 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++); 1305 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
1290 i += 7; 1306 i += (opcodeID == op_construct ? 7 : 5);
1291 break; 1307 break;
1292 } 1308 }
1293 case op_get_global_var: { 1309 case op_get_global_var: {
1294 JSVariableObject* globalObject = static_cast<JSVariableObject*>(inst ruction[i + 2].u.jsCell); 1310 JSVariableObject* globalObject = static_cast<JSVariableObject*>(inst ruction[i + 2].u.jsCell);
1295 m_jit.movl_i32r(asInteger(globalObject), X86::eax); 1311 m_jit.movl_i32r(asInteger(globalObject), X86::eax);
1296 emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand , X86::eax); 1312 emitGetVariableObjectRegister(X86::eax, instruction[i + 3].u.operand , X86::eax);
1297 emitPutResult(instruction[i + 1].u.operand); 1313 emitPutResult(instruction[i + 1].u.operand);
1298 i += 4; 1314 i += 4;
1299 break; 1315 break;
1300 } 1316 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 break; 1390 break;
1375 } 1391 }
1376 case op_resolve: { 1392 case op_resolve: {
1377 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u. operand]); 1393 Identifier* ident = &(m_codeBlock->identifiers[instruction[i + 2].u. operand]);
1378 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0); 1394 emitPutArgConstant(reinterpret_cast<unsigned>(ident), 0);
1379 emitCTICall(instruction + i, i, Machine::cti_op_resolve); 1395 emitCTICall(instruction + i, i, Machine::cti_op_resolve);
1380 emitPutResult(instruction[i + 1].u.operand); 1396 emitPutResult(instruction[i + 1].u.operand);
1381 i += 3; 1397 i += 3;
1382 break; 1398 break;
1383 } 1399 }
1384 case op_construct: {
1385 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
1386 i += 7;
1387 break;
1388 }
1389 case op_construct_verify: { 1400 case op_construct_verify: {
1390 emitGetArg(instruction[i + 1].u.operand, X86::eax); 1401 emitGetArg(instruction[i + 1].u.operand, X86::eax);
1391 1402
1392 m_jit.testl_i32r(JSImmediate::TagMask, X86::eax); 1403 m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
1393 X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJne(); 1404 X86Assembler::JmpSrc isImmediate = m_jit.emitUnlinkedJne();
1394 m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::e cx); 1405 m_jit.movl_mr(OBJECT_OFFSET(JSCell, m_structureID), X86::eax, X86::e cx);
1395 m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx); 1406 m_jit.cmpl_i32m(ObjectType, OBJECT_OFFSET(StructureID, m_typeInfo) + OBJECT_OFFSET(TypeInfo, m_type), X86::ecx);
1396 X86Assembler::JmpSrc isObject = m_jit.emitUnlinkedJe(); 1407 X86Assembler::JmpSrc isObject = m_jit.emitUnlinkedJe();
1397 1408
1398 m_jit.link(isImmediate, m_jit.label()); 1409 m_jit.link(isImmediate, m_jit.label());
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 } 1917 }
1907 case op_bitor: { 1918 case op_bitor: {
1908 emitGetArg(instruction[i + 2].u.operand, X86::eax); 1919 emitGetArg(instruction[i + 2].u.operand, X86::eax);
1909 emitGetArg(instruction[i + 3].u.operand, X86::edx); 1920 emitGetArg(instruction[i + 3].u.operand, X86::edx);
1910 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i); 1921 emitJumpSlowCaseIfNotImmNums(X86::eax, X86::edx, i);
1911 m_jit.orl_rr(X86::edx, X86::eax); 1922 m_jit.orl_rr(X86::edx, X86::eax);
1912 emitPutResult(instruction[i + 1].u.operand); 1923 emitPutResult(instruction[i + 1].u.operand);
1913 i += 5; 1924 i += 5;
1914 break; 1925 break;
1915 } 1926 }
1916 case op_call_eval: {
1917 compileOpCall(opcodeID, instruction + i, i, callLinkInfoIndex++);
1918 i += 7;
1919 break;
1920 }
1921 case op_throw: { 1927 case op_throw: {
1922 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx); 1928 emitGetPutArg(instruction[i + 1].u.operand, 0, X86::ecx);
1923 emitCTICall(instruction + i, i, Machine::cti_op_throw); 1929 emitCTICall(instruction + i, i, Machine::cti_op_throw);
1924 m_jit.addl_i8r(0x20, X86::esp); 1930 m_jit.addl_i8r(0x20, X86::esp);
1925 m_jit.popl_r(X86::ebx); 1931 m_jit.popl_r(X86::ebx);
1926 m_jit.popl_r(X86::edi); 1932 m_jit.popl_r(X86::edi);
1927 m_jit.popl_r(X86::esi); 1933 m_jit.popl_r(X86::esi);
1928 m_jit.ret(); 1934 m_jit.ret();
1929 i += 2; 1935 i += 2;
1930 break; 1936 break;
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after
2760 compileBinaryArithOpSlowCase(instruction + i, op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i); 2766 compileBinaryArithOpSlowCase(instruction + i, op_mul, iter, dst, src1, src2, OperandTypes::fromInt(instruction[i + 4].u.operand), i);
2761 i += 5; 2767 i += 5;
2762 break; 2768 break;
2763 } 2769 }
2764 2770
2765 case op_call: 2771 case op_call:
2766 case op_call_eval: 2772 case op_call_eval:
2767 case op_construct: { 2773 case op_construct: {
2768 int dst = instruction[i + 1].u.operand; 2774 int dst = instruction[i + 1].u.operand;
2769 int callee = instruction[i + 2].u.operand; 2775 int callee = instruction[i + 2].u.operand;
2770 int firstArg = instruction[i + 4].u.operand; 2776 int argCount = instruction[i + 3].u.operand;
2771 int argCount = instruction[i + 5].u.operand; 2777 int registerOffset = instruction[i + 4].u.operand;
2772 int registerOffset = instruction[i + 6].u.operand;
2773 2778
2774 m_jit.link(iter->from, m_jit.label()); 2779 m_jit.link(iter->from, m_jit.label());
2775 2780
2776 // The arguments have been set up on the hot path for op_call_eval 2781 // The arguments have been set up on the hot path for op_call_eval
2777 if (opcodeID != op_call_eval) 2782 if (opcodeID == op_call)
2778 compileOpCallSetupArgs(instruction + i, (opcodeID == op_construc t), false); 2783 compileOpCallSetupArgs(instruction + i);
2784 else if (opcodeID == op_construct)
2785 compileOpConstructSetupArgs(instruction + i);
2779 2786
2780 // Fast check for JS function. 2787 // Fast check for JS function.
2781 m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx); 2788 m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
2782 X86Assembler::JmpSrc callLinkFailNotObject = m_jit.emitUnlinkedJne() ; 2789 X86Assembler::JmpSrc callLinkFailNotObject = m_jit.emitUnlinkedJne() ;
2783 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVp tr), X86::ecx); 2790 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVp tr), X86::ecx);
2784 X86Assembler::JmpSrc callLinkFailNotJSFunction = m_jit.emitUnlinkedJ ne(); 2791 X86Assembler::JmpSrc callLinkFailNotJSFunction = m_jit.emitUnlinkedJ ne();
2785 2792
2786 // First, in the cale of a construct, allocate the new object. 2793 // First, in the case of a construct, allocate the new object.
2787 if (opcodeID == op_construct) { 2794 if (opcodeID == op_construct) {
2788 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruc t); 2795 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruc t);
2789 emitPutResult(firstArg); 2796 emitPutResult(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
2790 emitGetArg(callee, X86::ecx); 2797 emitGetArg(callee, X86::ecx);
2791 } 2798 }
2792 2799
2793 // Load the callee CodeBlock* into eax 2800 // Load the callee CodeBlock* into eax
2794 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_body), X86::ecx, X86::eax) ; 2801 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_body), X86::ecx, X86::eax) ;
2795 m_jit.movl_mr(OBJECT_OFFSET(FunctionBodyNode, m_code), X86::eax, X86 ::eax); 2802 m_jit.movl_mr(OBJECT_OFFSET(FunctionBodyNode, m_code), X86::eax, X86 ::eax);
2796 m_jit.testl_rr(X86::eax, X86::eax); 2803 m_jit.testl_rr(X86::eax, X86::eax);
2797 X86Assembler::JmpSrc hasCodeBlockForLink = m_jit.emitUnlinkedJne(); 2804 X86Assembler::JmpSrc hasCodeBlockForLink = m_jit.emitUnlinkedJne();
2798 emitCTICall(instruction + i, i, Machine::cti_op_call_JSFunction); 2805 emitCTICall(instruction + i, i, Machine::cti_op_call_JSFunction);
2799 emitGetArg(callee, X86::ecx); 2806 emitGetArg(callee, X86::ecx);
(...skipping 20 matching lines...) Expand all
2820 emitPutArgConstant(reinterpret_cast<unsigned>(info), 4); 2827 emitPutArgConstant(reinterpret_cast<unsigned>(info), 4);
2821 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLoca tion = 2828 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLoca tion =
2822 emitCTICall(instruction + i, i, Machine::cti_vm_lazyLinkCall); 2829 emitCTICall(instruction + i, i, Machine::cti_vm_lazyLinkCall);
2823 emitNakedCall(i, X86::eax); 2830 emitNakedCall(i, X86::eax);
2824 X86Assembler::JmpSrc storeResultForFirstRun = m_jit.emitUnlinkedJmp( ); 2831 X86Assembler::JmpSrc storeResultForFirstRun = m_jit.emitUnlinkedJmp( );
2825 2832
2826 // This is the address for the cold path *after* the first run (whic h tries to link the call). 2833 // This is the address for the cold path *after* the first run (whic h tries to link the call).
2827 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = m_jit.label(); 2834 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = m_jit.label();
2828 2835
2829 // The arguments have been set up on the hot path for op_call_eval 2836 // The arguments have been set up on the hot path for op_call_eval
2830 if (opcodeID != op_call_eval) 2837 if (opcodeID == op_call)
2831 compileOpCallSetupArgs(instruction + i, (opcodeID == op_construc t), false); 2838 compileOpCallSetupArgs(instruction + i);
2839 else if (opcodeID == op_construct)
2840 compileOpConstructSetupArgs(instruction + i);
2832 2841
2833 // Check for JSFunctions. 2842 // Check for JSFunctions.
2834 m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx); 2843 m_jit.testl_i32r(JSImmediate::TagMask, X86::ecx);
2835 X86Assembler::JmpSrc isNotObject = m_jit.emitUnlinkedJne(); 2844 X86Assembler::JmpSrc isNotObject = m_jit.emitUnlinkedJne();
2836 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVp tr), X86::ecx); 2845 m_jit.cmpl_i32m(reinterpret_cast<unsigned>(m_machine->m_jsFunctionVp tr), X86::ecx);
2837 X86Assembler::JmpSrc isJSFunction = m_jit.emitUnlinkedJe(); 2846 X86Assembler::JmpSrc isJSFunction = m_jit.emitUnlinkedJe();
2838 2847
2839 // This handles host functions 2848 // This handles host functions
2840 X86Assembler::JmpDst notJSFunctionlabel = m_jit.label(); 2849 X86Assembler::JmpDst notJSFunctionlabel = m_jit.label();
2841 m_jit.link(isNotObject, notJSFunctionlabel); 2850 m_jit.link(isNotObject, notJSFunctionlabel);
2842 m_jit.link(callLinkFailNotObject, notJSFunctionlabel); 2851 m_jit.link(callLinkFailNotObject, notJSFunctionlabel);
2843 m_jit.link(callLinkFailNotJSFunction, notJSFunctionlabel); 2852 m_jit.link(callLinkFailNotJSFunction, notJSFunctionlabel);
2844 emitCTICall(instruction + i, i, ((opcodeID == op_construct) ? Machin e::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction)); 2853 emitCTICall(instruction + i, i, ((opcodeID == op_construct) ? Machin e::cti_op_construct_NotJSConstruct : Machine::cti_op_call_NotJSFunction));
2845 X86Assembler::JmpSrc wasNotJSFunction = m_jit.emitUnlinkedJmp(); 2854 X86Assembler::JmpSrc wasNotJSFunction = m_jit.emitUnlinkedJmp();
2846 2855
2847 // Next, handle JSFunctions... 2856 // Next, handle JSFunctions...
2848 m_jit.link(isJSFunction, m_jit.label()); 2857 m_jit.link(isJSFunction, m_jit.label());
2849 2858
2850 // First, in the cale of a construct, allocate the new object. 2859 // First, in the case of a construct, allocate the new object.
2851 if (opcodeID == op_construct) { 2860 if (opcodeID == op_construct) {
2852 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruc t); 2861 emitCTICall(instruction, i, Machine::cti_op_construct_JSConstruc t);
2853 emitPutResult(firstArg); 2862 emitPutResult(registerOffset - RegisterFile::CallFrameHeaderSize - argCount);
2854 emitGetArg(callee, X86::ecx); 2863 emitGetArg(callee, X86::ecx);
2855 } 2864 }
2856 2865
2857 // Load the callee CodeBlock* into eax 2866 // Load the callee CodeBlock* into eax
2858 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_body), X86::ecx, X86::eax) ; 2867 m_jit.movl_mr(OBJECT_OFFSET(JSFunction, m_body), X86::ecx, X86::eax) ;
2859 m_jit.movl_mr(OBJECT_OFFSET(FunctionBodyNode, m_code), X86::eax, X86 ::eax); 2868 m_jit.movl_mr(OBJECT_OFFSET(FunctionBodyNode, m_code), X86::eax, X86 ::eax);
2860 m_jit.testl_rr(X86::eax, X86::eax); 2869 m_jit.testl_rr(X86::eax, X86::eax);
2861 X86Assembler::JmpSrc hasCodeBlock = m_jit.emitUnlinkedJne(); 2870 X86Assembler::JmpSrc hasCodeBlock = m_jit.emitUnlinkedJne();
2862 emitCTICall(instruction + i, i, Machine::cti_op_call_JSFunction); 2871 emitCTICall(instruction + i, i, Machine::cti_op_call_JSFunction);
2863 emitGetArg(callee, X86::ecx); 2872 emitGetArg(callee, X86::ecx);
(...skipping 24 matching lines...) Expand all
2888 X86Assembler::JmpDst storeResult = m_jit.label(); 2897 X86Assembler::JmpDst storeResult = m_jit.label();
2889 m_jit.link(wasNotJSFunction, storeResult); 2898 m_jit.link(wasNotJSFunction, storeResult);
2890 m_jit.link(storeResultForFirstRun, storeResult); 2899 m_jit.link(storeResultForFirstRun, storeResult);
2891 emitPutResult(dst); 2900 emitPutResult(dst);
2892 2901
2893 #if ENABLE(CODEBLOCK_SAMPLING) 2902 #if ENABLE(CODEBLOCK_SAMPLING)
2894 m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine-> sampler()->codeBlockSlot()); 2903 m_jit.movl_i32m(reinterpret_cast<unsigned>(m_codeBlock), m_machine-> sampler()->codeBlockSlot());
2895 #endif 2904 #endif
2896 ++callLinkInfoIndex; 2905 ++callLinkInfoIndex;
2897 2906
2898 i += 7; 2907 i += (opcodeID == op_construct ? 7 : 5);
2899 break; 2908 break;
2900 } 2909 }
2901 case op_to_jsnumber: { 2910 case op_to_jsnumber: {
2902 m_jit.link(iter->from, m_jit.label()); 2911 m_jit.link(iter->from, m_jit.label());
2903 m_jit.link(iter->from, m_jit.label()); 2912 m_jit.link(iter->from, m_jit.label());
2904 2913
2905 emitPutArg(X86::eax, 0); 2914 emitPutArg(X86::eax, 0);
2906 emitCTICall(instruction + i, i, Machine::cti_op_to_jsnumber); 2915 emitCTICall(instruction + i, i, Machine::cti_op_to_jsnumber);
2907 2916
2908 emitPutResult(instruction[i + 1].u.operand); 2917 emitPutResult(instruction[i + 1].u.operand);
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 void* code = jit.copy(); 3570 void* code = jit.copy();
3562 ASSERT(code); 3571 ASSERT(code);
3563 return code; 3572 return code;
3564 } 3573 }
3565 3574
3566 #endif // ENABLE(WREC) 3575 #endif // ENABLE(WREC)
3567 3576
3568 } // namespace JSC 3577 } // namespace JSC
3569 3578
3570 #endif // ENABLE(CTI) 3579 #endif // ENABLE(CTI)
OLDNEW
« no previous file with comments | « third_party/WebKit/JavaScriptCore/VM/CTI.h ('k') | third_party/WebKit/JavaScriptCore/VM/CodeBlock.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698