| Differences between
and this patch
- Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.cpp +86 lines
Line 0 Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.cpp_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#include "config.h"
27
#include "ArityCheckFailReturnThunks.h"
28
29
#if ENABLE(JIT)
30
31
#include "AssemblyHelpers.h"
32
33
namespace JSC {
34
35
ArityCheckFailReturnThunks::ArityCheckFailReturnThunks() { }
36
ArityCheckFailReturnThunks::~ArityCheckFailReturnThunks() { }
37
38
CodeLocationLabel* ArityCheckFailReturnThunks::returnPCsFor(
39
    VM& vm, unsigned numExpectedArgumentsIncludingThis)
40
{
41
    ASSERT(numExpectedArgumentsIncudingThis >= 1);
42
    
43
    HashMap<unsigned, std::unique_ptr<Data>>::iterator iter =
44
        m_map.find(numExpectedArgumentsIncludingThis);
45
    if (iter != m_map.end())
46
        return iter->value.m_returnPCs.get();
47
    
48
    AssemblyHelpers jit(&vm, 0);
49
    
50
    Vector<AssemblyHelpers::Label> returnLabels;
51
    
52
    for (unsigned i = 0; i < numExpectedArgumentsIncludingThis - 1; ++i) {
53
        returnLabels.append(jit.label());
54
        
55
        jit.loadPtr(
56
            AssemblyHelpers::Address(
57
                AssemblyHelpers::stackPointerRegister,
58
                (JSStack::CallFrameHeaderSize - JSStack::CallerFrameAndPCSize + numExpectedArgumentsIncludingThis) * sizeof(Register)),
59
            GPRInfo::regT1);
60
        
61
        jit.addPtr(
62
            AssemblyHelpers::TrustedImm32((i + 1) * sizeof(Register)),
63
            AssemblyHelpers::stackPointerRegister);
64
        
65
        jit.jump(GPRInfo::regT1);
66
    }
67
    
68
    LinkBuffer linkBuffer(vm, &jit, GLOBAL_THUNK_ID);
69
    
70
    std::unique_ptr<Data> data = std::make_unique<Data>();
71
    data->m_returnPCs = std::make_unique<CodeLocationLabel[]>(returnLabels.size());
72
    for (unsigned i = returnLabels.size(); i--;)
73
        data->m_returnPCs[i] = linkBuffer.locationOf(returnLabels[i]);
74
    data->m_ref = FINALIZE_CODE(linkBuffer, ("Arity check fail return thunk for numArgs = %u", numExpectedArgumentsIncludingThis));
75
    
76
    CodeLocationLabel* result = data->m_returnPCs.get();
77
    
78
    m_map.add(numExpectedArgumentsIncludingThis, std::move(data));
79
    
80
    return result;
81
}
82
83
} // namespace JSC
84
85
#endif // ENABLE(JIT)
86
- Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.h +58 lines
Line 0 Source/JavaScriptCore/jit/ArityCheckFailReturnThunks.h_sec1
1
/*
2
 * Copyright (C) 2013 Apple Inc. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24
 */
25
26
#ifndef ArityCheckFailReturnThunks_h
27
#define ArityCheckFailReturnThunks_h
28
29
#if ENABLE(JIT)
30
31
#include "CodeLocation.h"
32
#include <wtf/HashMap.h>
33
34
namespace JSC {
35
36
class ArityCheckFailReturnThunks {
37
public:
38
    ArityCheckFailReturnThunks();
39
    ~ArityCheckFailReturnThunks();
40
    
41
    // Returns a pointer to an array of return labels indexed by missingArgs.
42
    CodeLocationLabel* returnPCsFor(VM&, unsigned numExpectedArgumentsIncludingThis);
43
    
44
private:
45
    struct Data {
46
        std::unique_ptr<CodeLocationLabel[]> m_returnPCs;
47
        MacroAssemblerCodeRef m_ref;
48
    };
49
    
50
    HashMap<unsigned, std::unique_ptr<Data>> m_map;
51
};
52
53
} // namespace JSC
54
55
#endif // ENABLE(JIT)
56
57
#endif // ArityCheckFailReturnThunks_h
58
- Source/JavaScriptCore/jit/JIT.cpp +2 lines
Lines 576-581 CompilationResult JIT::privateCompile(JI Source/JavaScriptCore/jit/JIT.cpp_sec1
576
        if (returnValueGPR != regT0)
576
        if (returnValueGPR != regT0)
577
            move(returnValueGPR, regT0);
577
            move(returnValueGPR, regT0);
578
        branchTest32(Zero, regT0).linkTo(beginLabel, this);
578
        branchTest32(Zero, regT0).linkTo(beginLabel, this);
579
        move(TrustedImmPtr(m_vm->arityCheckFailReturnThunks->returnPCsFor(*m_vm, m_codeBlock->numParameters())), regT5);
580
        loadPtr(BaseIndex(regT5, regT0, TimesPtr), regT5);
579
        emitNakedCall(m_vm->getCTIStub(arityFixup).code());
581
        emitNakedCall(m_vm->getCTIStub(arityFixup).code());
580
582
581
#if !ASSERT_DISABLED
583
#if !ASSERT_DISABLED
- Source/JavaScriptCore/jit/ThunkGenerators.cpp -7 / +17 lines
Lines 440-453 MacroAssemblerCodeRef arityFixup(VM* vm) Source/JavaScriptCore/jit/ThunkGenerators.cpp_sec1
440
{
440
{
441
    JSInterfaceJIT jit(vm);
441
    JSInterfaceJIT jit(vm);
442
442
443
    // We enter with fixup count in regT0
443
    // We enter with fixup count in regT0 and the return thunk in regT5. We use
444
    // VM::currentReturnThunkPC instead of regT5 on X86-32.
444
#if USE(JSVALUE64)
445
#if USE(JSVALUE64)
445
#  if CPU(X86_64)
446
#  if CPU(X86_64)
446
    jit.pop(JSInterfaceJIT::regT4);
447
    jit.pop(JSInterfaceJIT::regT4);
447
#  endif
448
#  endif
449
    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT0);
448
    jit.neg64(JSInterfaceJIT::regT0);
450
    jit.neg64(JSInterfaceJIT::regT0);
449
    jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT3);
451
    jit.move(JSInterfaceJIT::callFrameRegister, JSInterfaceJIT::regT3);
450
    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * 8), JSInterfaceJIT::regT2);
452
    jit.load32(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, JSStack::ArgumentCount * sizeof(Register)), JSInterfaceJIT::regT2);
451
    jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::regT2);
453
    jit.add32(JSInterfaceJIT::TrustedImm32(JSStack::CallFrameHeaderSize), JSInterfaceJIT::regT2);
452
454
453
    // Move current frame down regT0 number of slots
455
    // Move current frame down regT0 number of slots
Lines 457-474 MacroAssemblerCodeRef arityFixup(VM* vm) Source/JavaScriptCore/jit/ThunkGenerators.cpp_sec2
457
    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
459
    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
458
    jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(copyLoop, &jit);
460
    jit.branchSub32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(copyLoop, &jit);
459
461
460
    // Fill in regT0 missing arg slots with undefined
462
    // Fill in regT0 - 1 missing arg slots with undefined
461
    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT2);
463
    jit.move(JSInterfaceJIT::regT0, JSInterfaceJIT::regT2);
462
    jit.move(JSInterfaceJIT::TrustedImm64(ValueUndefined), JSInterfaceJIT::regT1);
464
    jit.move(JSInterfaceJIT::TrustedImm64(ValueUndefined), JSInterfaceJIT::regT1);
465
    jit.add32(JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2);
463
    JSInterfaceJIT::Label fillUndefinedLoop(jit.label());
466
    JSInterfaceJIT::Label fillUndefinedLoop(jit.label());
464
    jit.store64(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
467
    jit.store64(JSInterfaceJIT::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
465
    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
468
    jit.addPtr(JSInterfaceJIT::TrustedImm32(8), JSInterfaceJIT::regT3);
466
    jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(fillUndefinedLoop, &jit);
469
    jit.branchAdd32(MacroAssembler::NonZero, JSInterfaceJIT::TrustedImm32(1), JSInterfaceJIT::regT2).linkTo(fillUndefinedLoop, &jit);
467
470
    
468
    // Adjust call frame register and stack pointer to account for missing args
471
    // Adjust call frame register and stack pointer to account for missing args
469
    jit.lshift64(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT0);
472
    jit.lshift64(JSInterfaceJIT::TrustedImm32(3), JSInterfaceJIT::regT1);
470
    jit.addPtr(JSInterfaceJIT::regT0, JSInterfaceJIT::callFrameRegister);
473
    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::callFrameRegister);
471
    jit.addPtr(JSInterfaceJIT::regT0, JSInterfaceJIT::stackPointerRegister);
474
    jit.addPtr(JSInterfaceJIT::regT1, JSInterfaceJIT::stackPointerRegister);
475
476
    // Save the original return PC.
477
    jit.loadPtr(JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT1);
478
    jit.storePtr(GPRInfo::regT1, MacroAssembler::BaseIndex(JSInterfaceJIT::regT3, JSInterfaceJIT::regT0, JSInterfaceJIT::TimesEight));
479
    
480
    // Install the new return PC.
481
    jit.storePtr(GPRInfo::regT5, JSInterfaceJIT::Address(JSInterfaceJIT::callFrameRegister, CallFrame::returnPCOffset()));
472
482
473
#  if CPU(X86_64)
483
#  if CPU(X86_64)
474
    jit.push(JSInterfaceJIT::regT4);
484
    jit.push(JSInterfaceJIT::regT4);
- Source/JavaScriptCore/runtime/VM.cpp +1 lines
Lines 266-271 VM::VM(VMType vmType, HeapType heapType) Source/JavaScriptCore/runtime/VM.cpp_sec1
266
266
267
#if ENABLE(JIT)
267
#if ENABLE(JIT)
268
    jitStubs = adoptPtr(new JITThunks());
268
    jitStubs = adoptPtr(new JITThunks());
269
    arityCheckFailReturnThunks = std::make_unique<ArityCheckFailReturnThunks>();
269
#endif
270
#endif
270
271
271
#if ENABLE(FTL_JIT)
272
#if ENABLE(FTL_JIT)
- Source/JavaScriptCore/runtime/VM.h -1 / +7 lines
Lines 64-69 Source/JavaScriptCore/runtime/VM.h_sec1
64
64
65
namespace JSC {
65
namespace JSC {
66
66
67
    class ArityCheckFailReturnThunks;
67
    class CodeBlock;
68
    class CodeBlock;
68
    class CodeCache;
69
    class CodeCache;
69
    class CommonIdentifiers;
70
    class CommonIdentifiers;
Lines 332-338 namespace JSC { Source/JavaScriptCore/runtime/VM.h_sec2
332
            return jitStubs->ctiStub(this, generator);
333
            return jitStubs->ctiStub(this, generator);
333
        }
334
        }
334
        NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
335
        NativeExecutable* getHostFunction(NativeFunction, Intrinsic);
335
#endif
336
        
337
        std::unique_ptr<ArityCheckFailReturnThunks> arityCheckFailReturnThunks;
338
#if CPU(X86)
339
        void* currentReturnThunkPC;
340
#endif // CPU(X86)
341
#endif // ENABLE(JIT)
336
#if ENABLE(FTL_JIT)
342
#if ENABLE(FTL_JIT)
337
        std::unique_ptr<FTL::Thunks> ftlThunks;
343
        std::unique_ptr<FTL::Thunks> ftlThunks;
338
#endif
344
#endif

Return to Bug 126043