fa9a7ed42aaf1ae383ea55a43b1acfca7b5b60c7
[WebKit.git] / Source / JavaScriptCore / llint / LLIntData.cpp
1 /*
2  * Copyright (C) 2011-2018 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 "LLIntData.h"
28
29 #include "ArithProfile.h"
30 #include "BytecodeConventions.h"
31 #include "CodeBlock.h"
32 #include "CodeType.h"
33 #include "Instruction.h"
34 #include "JSScope.h"
35 #include "LLIntCLoop.h"
36 #include "MaxFrameExtentForSlowPathCall.h"
37 #include "Opcode.h"
38 #include "PropertyOffset.h"
39 #include "ShadowChicken.h"
40 #include "WriteBarrier.h"
41
42 #define STATIC_ASSERT(cond) static_assert(cond, "LLInt assumes " #cond)
43
44
45 namespace JSC {
46
47 namespace LLInt {
48
49
50 uint8_t Data::s_exceptionInstructions[maxOpcodeLength + 1] = { };
51 Opcode g_opcodeMap[numOpcodeIDs] = { };
52 Opcode g_opcodeMapWide[numOpcodeIDs] = { };
53
54 #if !ENABLE(C_LOOP)
55 extern "C" void llint_entry(void*, void*);
56 #endif
57
58 void initialize()
59 {
60 #if ENABLE(C_LOOP)
61     CLoop::initialize();
62
63 #else // !ENABLE(C_LOOP)
64     llint_entry(&g_opcodeMap, &g_opcodeMapWide);
65
66     for (int i = 0; i < numOpcodeIDs; ++i) {
67         g_opcodeMap[i] = tagCodePtr(g_opcodeMap[i], BytecodePtrTag);
68         g_opcodeMapWide[i] = tagCodePtr(g_opcodeMapWide[i], BytecodePtrTag);
69     }
70
71     ASSERT(llint_throw_from_slow_path_trampoline < UINT8_MAX);
72     for (int i = 0; i < maxOpcodeLength + 1; ++i)
73         Data::s_exceptionInstructions[i] = llint_throw_from_slow_path_trampoline;
74 #endif // ENABLE(C_LOOP)
75 }
76
77 IGNORE_CLANG_WARNINGS_BEGIN("missing-noreturn")
78 void Data::performAssertions(VM& vm)
79 {
80     UNUSED_PARAM(vm);
81     
82     // Assertions to match LowLevelInterpreter.asm.  If you change any of this code, be
83     // prepared to change LowLevelInterpreter.asm as well!!
84
85 #if USE(JSVALUE64)
86     const ptrdiff_t CallFrameHeaderSlots = 5;
87 #else // USE(JSVALUE64) // i.e. 32-bit version
88     const ptrdiff_t CallFrameHeaderSlots = 4;
89 #endif
90     const ptrdiff_t MachineRegisterSize = sizeof(CPURegister);
91     const ptrdiff_t SlotSize = 8;
92
93     STATIC_ASSERT(sizeof(Register) == SlotSize);
94     STATIC_ASSERT(CallFrame::headerSizeInRegisters == CallFrameHeaderSlots);
95
96     ASSERT(!CallFrame::callerFrameOffset());
97     STATIC_ASSERT(CallerFrameAndPC::sizeInRegisters == (MachineRegisterSize * 2) / SlotSize);
98     ASSERT(CallFrame::returnPCOffset() == CallFrame::callerFrameOffset() + MachineRegisterSize);
99     ASSERT(CallFrameSlot::codeBlock * sizeof(Register) == CallFrame::returnPCOffset() + MachineRegisterSize);
100     STATIC_ASSERT(CallFrameSlot::callee * sizeof(Register) == CallFrameSlot::codeBlock * sizeof(Register) + SlotSize);
101     STATIC_ASSERT(CallFrameSlot::argumentCount * sizeof(Register) == CallFrameSlot::callee * sizeof(Register) + SlotSize);
102     STATIC_ASSERT(CallFrameSlot::thisArgument * sizeof(Register) == CallFrameSlot::argumentCount * sizeof(Register) + SlotSize);
103     STATIC_ASSERT(CallFrame::headerSizeInRegisters == CallFrameSlot::thisArgument);
104
105     ASSERT(CallFrame::argumentOffsetIncludingThis(0) == CallFrameSlot::thisArgument);
106
107 #if CPU(BIG_ENDIAN)
108     STATIC_ASSERT(TagOffset == 0);
109     STATIC_ASSERT(PayloadOffset == 4);
110 #else
111     STATIC_ASSERT(TagOffset == 4);
112     STATIC_ASSERT(PayloadOffset == 0);
113 #endif
114 #if USE(JSVALUE32_64)
115     STATIC_ASSERT(JSValue::Int32Tag == static_cast<unsigned>(-1));
116     STATIC_ASSERT(JSValue::BooleanTag == static_cast<unsigned>(-2));
117     STATIC_ASSERT(JSValue::NullTag == static_cast<unsigned>(-3));
118     STATIC_ASSERT(JSValue::UndefinedTag == static_cast<unsigned>(-4));
119     STATIC_ASSERT(JSValue::CellTag == static_cast<unsigned>(-5));
120     STATIC_ASSERT(JSValue::EmptyValueTag == static_cast<unsigned>(-6));
121     STATIC_ASSERT(JSValue::DeletedValueTag == static_cast<unsigned>(-7));
122     STATIC_ASSERT(JSValue::LowestTag == static_cast<unsigned>(-7));
123 #else
124     STATIC_ASSERT(TagBitTypeOther == 0x2);
125     STATIC_ASSERT(TagBitBool == 0x4);
126     STATIC_ASSERT(TagBitUndefined == 0x8);
127     STATIC_ASSERT(ValueEmpty == 0x0);
128     STATIC_ASSERT(ValueFalse == (TagBitTypeOther | TagBitBool));
129     STATIC_ASSERT(ValueTrue == (TagBitTypeOther | TagBitBool | 1));
130     STATIC_ASSERT(ValueUndefined == (TagBitTypeOther | TagBitUndefined));
131     STATIC_ASSERT(ValueNull == TagBitTypeOther);
132 #endif
133
134 #if ENABLE(C_LOOP)
135     ASSERT(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() == 1);
136 #elif USE(JSVALUE32_64)
137     ASSERT(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() == 1);
138 #elif (CPU(X86_64) && !OS(WINDOWS))  || CPU(ARM64)
139     ASSERT(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() == 4);
140 #elif (CPU(X86_64) && OS(WINDOWS))
141     ASSERT(CodeBlock::llintBaselineCalleeSaveSpaceAsVirtualRegisters() == 4);
142 #endif
143
144     ASSERT(!(reinterpret_cast<ptrdiff_t>((reinterpret_cast<WriteBarrier<JSCell>*>(0x4000)->slot())) - 0x4000));
145
146     // FIXME: make these assertions less horrible.
147 #if !ASSERT_DISABLED
148     Vector<int> testVector;
149     testVector.resize(42);
150     ASSERT(bitwise_cast<uint32_t*>(&testVector)[sizeof(void*)/sizeof(uint32_t) + 1] == 42);
151     ASSERT(bitwise_cast<int**>(&testVector)[0] == testVector.begin());
152 #endif
153
154     {
155         ArithProfile arithProfile;
156         arithProfile.lhsSawInt32();
157         arithProfile.rhsSawInt32();
158         ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntInt().bits());
159         STATIC_ASSERT(ArithProfile::observedBinaryIntInt().lhsObservedType().isOnlyInt32());
160         STATIC_ASSERT(ArithProfile::observedBinaryIntInt().rhsObservedType().isOnlyInt32());
161     }
162     {
163         ArithProfile arithProfile;
164         arithProfile.lhsSawNumber();
165         arithProfile.rhsSawInt32();
166         ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberInt().bits());
167         STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().lhsObservedType().isOnlyNumber());
168         STATIC_ASSERT(ArithProfile::observedBinaryNumberInt().rhsObservedType().isOnlyInt32());
169     }
170     {
171         ArithProfile arithProfile;
172         arithProfile.lhsSawNumber();
173         arithProfile.rhsSawNumber();
174         ASSERT(arithProfile.bits() == ArithProfile::observedBinaryNumberNumber().bits());
175         STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().lhsObservedType().isOnlyNumber());
176         STATIC_ASSERT(ArithProfile::observedBinaryNumberNumber().rhsObservedType().isOnlyNumber());
177     }
178     {
179         ArithProfile arithProfile;
180         arithProfile.lhsSawInt32();
181         arithProfile.rhsSawNumber();
182         ASSERT(arithProfile.bits() == ArithProfile::observedBinaryIntNumber().bits());
183         STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().lhsObservedType().isOnlyInt32());
184         STATIC_ASSERT(ArithProfile::observedBinaryIntNumber().rhsObservedType().isOnlyNumber());
185     }
186 }
187 IGNORE_CLANG_WARNINGS_END
188
189 } } // namespace JSC::LLInt