Templatize CodePtr/Refs/FunctionPtrs with PtrTags.
[WebKit-https.git] / Source / JavaScriptCore / runtime / ExecutableBase.cpp
1 /*
2  * Copyright (C) 2009-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
28 #include "BatchedTransitionOptimizer.h"
29 #include "CodeBlock.h"
30 #include "Debugger.h"
31 #include "EvalCodeBlock.h"
32 #include "FunctionCodeBlock.h"
33 #include "JIT.h"
34 #include "JSCInlines.h"
35 #include "LLIntEntrypoint.h"
36 #include "ModuleProgramCodeBlock.h"
37 #include "Parser.h"
38 #include "ProgramCodeBlock.h"
39 #include "TypeProfiler.h"
40 #include "VMInlines.h"
41 #include <wtf/CommaPrinter.h>
42
43 namespace JSC {
44
45 const ClassInfo ExecutableBase::s_info = { "Executable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(ExecutableBase) };
46
47 void ExecutableBase::destroy(JSCell* cell)
48 {
49     static_cast<ExecutableBase*>(cell)->ExecutableBase::~ExecutableBase();
50 }
51
52 void ExecutableBase::clearCode()
53 {
54 #if ENABLE(JIT)
55     m_jitCodeForCall = nullptr;
56     m_jitCodeForConstruct = nullptr;
57     m_jitCodeForCallWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>();
58     m_jitCodeForConstructWithArityCheck = MacroAssemblerCodePtr<JSEntryPtrTag>();
59 #endif
60     m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
61     m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;
62     VM& vm = *this->vm();
63
64
65     if (structure(vm)->classInfo() == FunctionExecutable::info()) {
66         FunctionExecutable* executable = static_cast<FunctionExecutable*>(this);
67         executable->m_codeBlockForCall.clear();
68         executable->m_codeBlockForConstruct.clear();
69         return;
70     }
71
72     if (structure(vm)->classInfo() == EvalExecutable::info()) {
73         EvalExecutable* executable = static_cast<EvalExecutable*>(this);
74         executable->m_evalCodeBlock.clear();
75         executable->m_unlinkedEvalCodeBlock.clear();
76         return;
77     }
78     
79     if (structure(vm)->classInfo() == ProgramExecutable::info()) {
80         ProgramExecutable* executable = static_cast<ProgramExecutable*>(this);
81         executable->m_programCodeBlock.clear();
82         executable->m_unlinkedProgramCodeBlock.clear();
83         return;
84     }
85
86     if (structure(vm)->classInfo() == ModuleProgramExecutable::info()) {
87         ModuleProgramExecutable* executable = static_cast<ModuleProgramExecutable*>(this);
88         executable->m_moduleProgramCodeBlock.clear();
89         executable->m_unlinkedModuleProgramCodeBlock.clear();
90         executable->m_moduleEnvironmentSymbolTable.clear();
91         return;
92     }
93     
94     ASSERT(structure(vm)->classInfo() == NativeExecutable::info());
95 }
96
97 void ExecutableBase::dump(PrintStream& out) const
98 {
99     VM& vm = *this->vm();
100     ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
101
102     if (classInfo(vm) == NativeExecutable::info()) {
103         NativeExecutable* native = jsCast<NativeExecutable*>(realThis);
104         out.print("NativeExecutable:", RawPointer(bitwise_cast<void*>(native->function())), "/", RawPointer(bitwise_cast<void*>(native->constructor())));
105         return;
106     }
107     
108     if (classInfo(vm) == EvalExecutable::info()) {
109         EvalExecutable* eval = jsCast<EvalExecutable*>(realThis);
110         if (CodeBlock* codeBlock = eval->codeBlock())
111             out.print(*codeBlock);
112         else
113             out.print("EvalExecutable w/o CodeBlock");
114         return;
115     }
116     
117     if (classInfo(vm) == ProgramExecutable::info()) {
118         ProgramExecutable* eval = jsCast<ProgramExecutable*>(realThis);
119         if (CodeBlock* codeBlock = eval->codeBlock())
120             out.print(*codeBlock);
121         else
122             out.print("ProgramExecutable w/o CodeBlock");
123         return;
124     }
125
126     if (classInfo(vm) == ModuleProgramExecutable::info()) {
127         ModuleProgramExecutable* executable = jsCast<ModuleProgramExecutable*>(realThis);
128         if (CodeBlock* codeBlock = executable->codeBlock())
129             out.print(*codeBlock);
130         else
131             out.print("ModuleProgramExecutable w/o CodeBlock");
132         return;
133     }
134     
135     FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis);
136     if (!function->eitherCodeBlock())
137         out.print("FunctionExecutable w/o CodeBlock");
138     else {
139         CommaPrinter comma("/");
140         if (function->codeBlockForCall())
141             out.print(comma, *function->codeBlockForCall());
142         if (function->codeBlockForConstruct())
143             out.print(comma, *function->codeBlockForConstruct());
144     }
145 }
146
147 CodeBlockHash ExecutableBase::hashFor(CodeSpecializationKind kind) const
148 {
149     if (this->classInfo(*this->vm()) == NativeExecutable::info())
150         return jsCast<const NativeExecutable*>(this)->hashFor(kind);
151     
152     return jsCast<const ScriptExecutable*>(this)->hashFor(kind);
153 }
154
155 } // namespace JSC