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 |