| OLD | NEW |
| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 | 138 |
| 139 emitGetVirtualRegister(callee, regT2); | 139 emitGetVirtualRegister(callee, regT2); |
| 140 // The arguments have been set up on the hot path for op_call_eval | 140 // The arguments have been set up on the hot path for op_call_eval |
| 141 if (opcodeID == op_call) | 141 if (opcodeID == op_call) |
| 142 compileOpCallSetupArgs(instruction); | 142 compileOpCallSetupArgs(instruction); |
| 143 else if (opcodeID == op_construct) | 143 else if (opcodeID == op_construct) |
| 144 compileOpConstructSetupArgs(instruction); | 144 compileOpConstructSetupArgs(instruction); |
| 145 | 145 |
| 146 // Check for JSFunctions. | 146 // Check for JSFunctions. |
| 147 emitJumpSlowCaseIfNotJSCell(regT2); | 147 emitJumpSlowCaseIfNotJSCell(regT2); |
| 148 addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_interpreter->m_jsFu
nctionVptr))); | 148 addSlowCase(branchPtr(NotEqual, Address(regT2), ImmPtr(m_globalData->jsFunct
ionVPtr))); |
| 149 | 149 |
| 150 // First, in the case of a construct, allocate the new object. | 150 // First, in the case of a construct, allocate the new object. |
| 151 if (opcodeID == op_construct) { | 151 if (opcodeID == op_construct) { |
| 152 emitCTICall(JITStubs::cti_op_construct_JSConstruct); | 152 emitCTICall(JITStubs::cti_op_construct_JSConstruct); |
| 153 emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSiz
e - argCount); | 153 emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSiz
e - argCount); |
| 154 emitGetVirtualRegister(callee, regT2); | 154 emitGetVirtualRegister(callee, regT2); |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Speculatively roll the callframe, assuming argCount will match the arity. | 157 // Speculatively roll the callframe, assuming argCount will match the arity. |
| 158 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::Caller
Frame + registerOffset) * static_cast<int>(sizeof(Register)))); | 158 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::Caller
Frame + registerOffset) * static_cast<int>(sizeof(Register)))); |
| 159 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrame
Register); | 159 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrame
Register); |
| 160 move(Imm32(argCount), regT1); | 160 move(Imm32(argCount), regT1); |
| 161 | 161 |
| 162 emitNakedCall(m_interpreter->m_ctiVirtualCall); | 162 emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); |
| 163 | 163 |
| 164 if (opcodeID == op_call_eval) | 164 if (opcodeID == op_call_eval) |
| 165 wasEval.link(this); | 165 wasEval.link(this); |
| 166 | 166 |
| 167 // Put the return value in dst. In the interpreter, op_ret does this. | 167 // Put the return value in dst. In the interpreter, op_ret does this. |
| 168 emitPutVirtualRegister(dst); | 168 emitPutVirtualRegister(dst); |
| 169 | 169 |
| 170 sampleCodeBlock(m_codeBlock); | 170 sampleCodeBlock(m_codeBlock); |
| 171 } | 171 } |
| 172 | 172 |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 linkSlowCase(iter); | 259 linkSlowCase(iter); |
| 260 | 260 |
| 261 // The arguments have been set up on the hot path for op_call_eval | 261 // The arguments have been set up on the hot path for op_call_eval |
| 262 if (opcodeID == op_call) | 262 if (opcodeID == op_call) |
| 263 compileOpCallSetupArgs(instruction); | 263 compileOpCallSetupArgs(instruction); |
| 264 else if (opcodeID == op_construct) | 264 else if (opcodeID == op_construct) |
| 265 compileOpConstructSetupArgs(instruction); | 265 compileOpConstructSetupArgs(instruction); |
| 266 | 266 |
| 267 // Fast check for JS function. | 267 // Fast check for JS function. |
| 268 Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT2); | 268 Jump callLinkFailNotObject = emitJumpIfNotJSCell(regT2); |
| 269 Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT2), ImmPtr(
m_interpreter->m_jsFunctionVptr)); | 269 Jump callLinkFailNotJSFunction = branchPtr(NotEqual, Address(regT2), ImmPtr(
m_globalData->jsFunctionVPtr)); |
| 270 | 270 |
| 271 // First, in the case of a construct, allocate the new object. | 271 // First, in the case of a construct, allocate the new object. |
| 272 if (opcodeID == op_construct) { | 272 if (opcodeID == op_construct) { |
| 273 emitCTICall(JITStubs::cti_op_construct_JSConstruct); | 273 emitCTICall(JITStubs::cti_op_construct_JSConstruct); |
| 274 emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSiz
e - argCount); | 274 emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSiz
e - argCount); |
| 275 emitGetVirtualRegister(callee, regT2); | 275 emitGetVirtualRegister(callee, regT2); |
| 276 } | 276 } |
| 277 | 277 |
| 278 move(Imm32(argCount), regT1); | 278 move(Imm32(argCount), regT1); |
| 279 | 279 |
| 280 // Speculatively roll the callframe, assuming argCount will match the arity. | 280 // Speculatively roll the callframe, assuming argCount will match the arity. |
| 281 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::Caller
Frame + registerOffset) * static_cast<int>(sizeof(Register)))); | 281 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::Caller
Frame + registerOffset) * static_cast<int>(sizeof(Register)))); |
| 282 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrame
Register); | 282 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrame
Register); |
| 283 | 283 |
| 284 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = | 284 m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = |
| 285 emitNakedCall(m_interpreter->m_ctiVirtualCallPreLink); | 285 emitNakedCall(m_globalData->jitStubs.ctiVirtualCallPreLink()); |
| 286 | 286 |
| 287 Jump storeResultForFirstRun = jump(); | 287 Jump storeResultForFirstRun = jump(); |
| 288 | 288 |
| 289 // FIXME: this label can be removed, since it is a fixed offset from 'callReturn
Location'. | 289 // FIXME: this label can be removed, since it is a fixed offset from 'callReturn
Location'. |
| 290 // This is the address for the cold path *after* the first run (which tries
to link the call). | 290 // This is the address for the cold path *after* the first run (which tries
to link the call). |
| 291 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = MacroA
ssembler::Label(this); | 291 m_callStructureStubCompilationInfo[callLinkInfoIndex].coldPathOther = MacroA
ssembler::Label(this); |
| 292 | 292 |
| 293 // The arguments have been set up on the hot path for op_call_eval | 293 // The arguments have been set up on the hot path for op_call_eval |
| 294 if (opcodeID == op_call) | 294 if (opcodeID == op_call) |
| 295 compileOpCallSetupArgs(instruction); | 295 compileOpCallSetupArgs(instruction); |
| 296 else if (opcodeID == op_construct) | 296 else if (opcodeID == op_construct) |
| 297 compileOpConstructSetupArgs(instruction); | 297 compileOpConstructSetupArgs(instruction); |
| 298 | 298 |
| 299 // Check for JSFunctions. | 299 // Check for JSFunctions. |
| 300 Jump isNotObject = emitJumpIfNotJSCell(regT2); | 300 Jump isNotObject = emitJumpIfNotJSCell(regT2); |
| 301 Jump isJSFunction = branchPtr(Equal, Address(regT2), ImmPtr(m_interpreter->m
_jsFunctionVptr)); | 301 Jump isJSFunction = branchPtr(Equal, Address(regT2), ImmPtr(m_globalData->js
FunctionVPtr)); |
| 302 | 302 |
| 303 // This handles host functions | 303 // This handles host functions |
| 304 isNotObject.link(this); | 304 isNotObject.link(this); |
| 305 callLinkFailNotObject.link(this); | 305 callLinkFailNotObject.link(this); |
| 306 callLinkFailNotJSFunction.link(this); | 306 callLinkFailNotJSFunction.link(this); |
| 307 emitCTICall(((opcodeID == op_construct) ? JITStubs::cti_op_construct_NotJSCo
nstruct : JITStubs::cti_op_call_NotJSFunction)); | 307 emitCTICall(((opcodeID == op_construct) ? JITStubs::cti_op_construct_NotJSCo
nstruct : JITStubs::cti_op_call_NotJSFunction)); |
| 308 Jump wasNotJSFunction = jump(); | 308 Jump wasNotJSFunction = jump(); |
| 309 | 309 |
| 310 // Next, handle JSFunctions... | 310 // Next, handle JSFunctions... |
| 311 isJSFunction.link(this); | 311 isJSFunction.link(this); |
| 312 | 312 |
| 313 // First, in the case of a construct, allocate the new object. | 313 // First, in the case of a construct, allocate the new object. |
| 314 if (opcodeID == op_construct) { | 314 if (opcodeID == op_construct) { |
| 315 emitCTICall(JITStubs::cti_op_construct_JSConstruct); | 315 emitCTICall(JITStubs::cti_op_construct_JSConstruct); |
| 316 emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSiz
e - argCount); | 316 emitPutVirtualRegister(registerOffset - RegisterFile::CallFrameHeaderSiz
e - argCount); |
| 317 emitGetVirtualRegister(callee, regT2); | 317 emitGetVirtualRegister(callee, regT2); |
| 318 } | 318 } |
| 319 | 319 |
| 320 // Speculatively roll the callframe, assuming argCount will match the arity. | 320 // Speculatively roll the callframe, assuming argCount will match the arity. |
| 321 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::Caller
Frame + registerOffset) * static_cast<int>(sizeof(Register)))); | 321 storePtr(callFrameRegister, Address(callFrameRegister, (RegisterFile::Caller
Frame + registerOffset) * static_cast<int>(sizeof(Register)))); |
| 322 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrame
Register); | 322 addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrame
Register); |
| 323 move(Imm32(argCount), regT1); | 323 move(Imm32(argCount), regT1); |
| 324 | 324 |
| 325 emitNakedCall(m_interpreter->m_ctiVirtualCall); | 325 emitNakedCall(m_globalData->jitStubs.ctiVirtualCall()); |
| 326 | 326 |
| 327 // Put the return value in dst. In the interpreter, op_ret does this. | 327 // Put the return value in dst. In the interpreter, op_ret does this. |
| 328 wasNotJSFunction.link(this); | 328 wasNotJSFunction.link(this); |
| 329 storeResultForFirstRun.link(this); | 329 storeResultForFirstRun.link(this); |
| 330 emitPutVirtualRegister(dst); | 330 emitPutVirtualRegister(dst); |
| 331 | 331 |
| 332 sampleCodeBlock(m_codeBlock); | 332 sampleCodeBlock(m_codeBlock); |
| 333 } | 333 } |
| 334 | 334 |
| 335 #endif | 335 #endif |
| 336 | 336 |
| 337 } // namespace JSC | 337 } // namespace JSC |
| 338 | 338 |
| 339 #endif // ENABLE(JIT) | 339 #endif // ENABLE(JIT) |
| OLD | NEW |