2 * Copyright (C) 2009, 2010, 2013-2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "ArityCheckMode.h"
31 #include "CodeBlockHash.h"
32 #include "CodeSpecializationKind.h"
33 #include "CompilationResult.h"
35 #include "HandlerInfo.h"
36 #include "InferredValue.h"
38 #include "JSGlobalObject.h"
39 #include "RegisterPreservationMode.h"
40 #include "SamplingTool.h"
41 #include "SourceCode.h"
43 #include "UnlinkedCodeBlock.h"
50 class FunctionCodeBlock
;
51 class LLIntOffsetsExtractor
;
52 class ProgramCodeBlock
;
55 enum CompilationKind
{ FirstCompilation
, OptimizingCompilation
};
57 inline bool isCall(CodeSpecializationKind kind
)
59 if (kind
== CodeForCall
)
61 ASSERT(kind
== CodeForConstruct
);
65 class ExecutableBase
: public JSCell
{
69 static const int NUM_PARAMETERS_IS_HOST
= 0;
70 static const int NUM_PARAMETERS_NOT_COMPILED
= -1;
72 ExecutableBase(VM
& vm
, Structure
* structure
, int numParameters
)
73 : JSCell(vm
, structure
)
74 , m_numParametersForCall(numParameters
)
75 , m_numParametersForConstruct(numParameters
)
79 void finishCreation(VM
& vm
)
81 Base::finishCreation(vm
);
86 static const unsigned StructureFlags
= Base::StructureFlags
;
88 static const bool needsDestruction
= true;
89 static void destroy(JSCell
*);
91 CodeBlockHash
hashFor(CodeSpecializationKind
) const;
93 bool isEvalExecutable()
95 return type() == EvalExecutableType
;
97 bool isFunctionExecutable()
99 return type() == FunctionExecutableType
;
101 bool isProgramExecutable()
103 return type() == ProgramExecutableType
;
106 bool isHostFunction() const
108 ASSERT((m_numParametersForCall
== NUM_PARAMETERS_IS_HOST
) == (m_numParametersForConstruct
== NUM_PARAMETERS_IS_HOST
));
109 return m_numParametersForCall
== NUM_PARAMETERS_IS_HOST
;
112 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(vm
, globalObject
, proto
, TypeInfo(CellType
, StructureFlags
), info()); }
119 int m_numParametersForCall
;
120 int m_numParametersForConstruct
;
123 static void clearCodeVirtual(ExecutableBase
*);
125 PassRefPtr
<JITCode
> generatedJITCodeForCall()
127 ASSERT(m_jitCodeForCall
);
128 return m_jitCodeForCall
;
131 PassRefPtr
<JITCode
> generatedJITCodeForConstruct()
133 ASSERT(m_jitCodeForConstruct
);
134 return m_jitCodeForConstruct
;
137 PassRefPtr
<JITCode
> generatedJITCodeFor(CodeSpecializationKind kind
)
139 if (kind
== CodeForCall
)
140 return generatedJITCodeForCall();
141 ASSERT(kind
== CodeForConstruct
);
142 return generatedJITCodeForConstruct();
145 MacroAssemblerCodePtr
entrypointFor(
146 VM
& vm
, CodeSpecializationKind kind
, ArityCheckMode arity
, RegisterPreservationMode registers
)
148 // Check if we have a cached result. We only have it for arity check because we use the
149 // no-arity entrypoint in non-virtual calls, which will "cache" this value directly in
151 if (arity
== MustCheckArity
) {
155 case RegisterPreservationNotRequired
:
156 if (MacroAssemblerCodePtr result
= m_jitCodeForCallWithArityCheck
)
159 case MustPreserveRegisters
:
160 if (MacroAssemblerCodePtr result
= m_jitCodeForCallWithArityCheckAndPreserveRegs
)
165 case CodeForConstruct
:
167 case RegisterPreservationNotRequired
:
168 if (MacroAssemblerCodePtr result
= m_jitCodeForConstructWithArityCheck
)
171 case MustPreserveRegisters
:
172 if (MacroAssemblerCodePtr result
= m_jitCodeForConstructWithArityCheckAndPreserveRegs
)
179 MacroAssemblerCodePtr result
=
180 generatedJITCodeFor(kind
)->addressForCall(vm
, this, arity
, registers
);
181 if (arity
== MustCheckArity
) {
182 // Cache the result; this is necessary for the JIT's virtual call optimizations.
186 case RegisterPreservationNotRequired
:
187 m_jitCodeForCallWithArityCheck
= result
;
189 case MustPreserveRegisters
:
190 m_jitCodeForCallWithArityCheckAndPreserveRegs
= result
;
194 case CodeForConstruct
:
196 case RegisterPreservationNotRequired
:
197 m_jitCodeForConstructWithArityCheck
= result
;
199 case MustPreserveRegisters
:
200 m_jitCodeForConstructWithArityCheckAndPreserveRegs
= result
;
209 static ptrdiff_t offsetOfJITCodeWithArityCheckFor(
210 CodeSpecializationKind kind
, RegisterPreservationMode registers
)
215 case RegisterPreservationNotRequired
:
216 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForCallWithArityCheck
);
217 case MustPreserveRegisters
:
218 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForCallWithArityCheckAndPreserveRegs
);
220 case CodeForConstruct
:
222 case RegisterPreservationNotRequired
:
223 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForConstructWithArityCheck
);
224 case MustPreserveRegisters
:
225 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForConstructWithArityCheckAndPreserveRegs
);
228 RELEASE_ASSERT_NOT_REACHED();
232 static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind
)
234 if (kind
== CodeForCall
)
235 return OBJECT_OFFSETOF(ExecutableBase
, m_numParametersForCall
);
236 ASSERT(kind
== CodeForConstruct
);
237 return OBJECT_OFFSETOF(ExecutableBase
, m_numParametersForConstruct
);
240 bool hasJITCodeForCall() const
242 return m_numParametersForCall
>= 0;
245 bool hasJITCodeForConstruct() const
247 return m_numParametersForConstruct
>= 0;
250 bool hasJITCodeFor(CodeSpecializationKind kind
) const
252 if (kind
== CodeForCall
)
253 return hasJITCodeForCall();
254 ASSERT(kind
== CodeForConstruct
);
255 return hasJITCodeForConstruct();
258 // Intrinsics are only for calls, currently.
259 Intrinsic
intrinsic() const;
261 Intrinsic
intrinsicFor(CodeSpecializationKind kind
) const
268 void dump(PrintStream
&) const;
271 RefPtr
<JITCode
> m_jitCodeForCall
;
272 RefPtr
<JITCode
> m_jitCodeForConstruct
;
273 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck
;
274 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck
;
275 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheckAndPreserveRegs
;
276 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheckAndPreserveRegs
;
279 class NativeExecutable final
: public ExecutableBase
{
281 friend class LLIntOffsetsExtractor
;
283 typedef ExecutableBase Base
;
284 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
286 static NativeExecutable
* create(VM
& vm
, PassRefPtr
<JITCode
> callThunk
, NativeFunction function
, PassRefPtr
<JITCode
> constructThunk
, NativeFunction constructor
, Intrinsic intrinsic
)
288 NativeExecutable
* executable
;
289 executable
= new (NotNull
, allocateCell
<NativeExecutable
>(vm
.heap
)) NativeExecutable(vm
, function
, constructor
);
290 executable
->finishCreation(vm
, callThunk
, constructThunk
, intrinsic
);
294 static void destroy(JSCell
*);
296 CodeBlockHash
hashFor(CodeSpecializationKind
) const;
298 NativeFunction
function() { return m_function
; }
299 NativeFunction
constructor() { return m_constructor
; }
301 NativeFunction
nativeFunctionFor(CodeSpecializationKind kind
)
303 if (kind
== CodeForCall
)
305 ASSERT(kind
== CodeForConstruct
);
306 return constructor();
309 static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind
)
311 if (kind
== CodeForCall
)
312 return OBJECT_OFFSETOF(NativeExecutable
, m_function
);
313 ASSERT(kind
== CodeForConstruct
);
314 return OBJECT_OFFSETOF(NativeExecutable
, m_constructor
);
317 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(vm
, globalObject
, proto
, TypeInfo(CellType
, StructureFlags
), info()); }
321 Intrinsic
intrinsic() const;
324 void finishCreation(VM
& vm
, PassRefPtr
<JITCode
> callThunk
, PassRefPtr
<JITCode
> constructThunk
, Intrinsic intrinsic
)
326 Base::finishCreation(vm
);
327 m_jitCodeForCall
= callThunk
;
328 m_jitCodeForConstruct
= constructThunk
;
329 m_intrinsic
= intrinsic
;
333 NativeExecutable(VM
& vm
, NativeFunction function
, NativeFunction constructor
)
334 : ExecutableBase(vm
, vm
.nativeExecutableStructure
.get(), NUM_PARAMETERS_IS_HOST
)
335 , m_function(function
)
336 , m_constructor(constructor
)
340 NativeFunction m_function
;
341 NativeFunction m_constructor
;
343 Intrinsic m_intrinsic
;
346 class ScriptExecutable
: public ExecutableBase
{
348 typedef ExecutableBase Base
;
349 static const unsigned StructureFlags
= Base::StructureFlags
;
351 static void destroy(JSCell
*);
353 CodeBlockHash
hashFor(CodeSpecializationKind
) const;
355 const SourceCode
& source() const { return m_source
; }
356 intptr_t sourceID() const { return m_source
.providerID(); }
357 const String
& sourceURL() const { return m_source
.provider()->url(); }
358 int firstLine() const { return m_firstLine
; }
359 void setOverrideLineNumber(int overrideLineNumber
) { m_overrideLineNumber
= overrideLineNumber
; }
360 bool hasOverrideLineNumber() const { return m_overrideLineNumber
!= -1; }
361 int overrideLineNumber() const { return m_overrideLineNumber
; }
362 int lastLine() const { return m_lastLine
; }
363 unsigned startColumn() const { return m_startColumn
; }
364 unsigned endColumn() const { return m_endColumn
; }
365 unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset
; }
366 unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset
; }
368 bool usesEval() const { return m_features
& EvalFeature
; }
369 bool usesArguments() const { return m_features
& ArgumentsFeature
; }
370 bool needsActivation() const { return m_hasCapturedVariables
|| m_features
& (EvalFeature
| WithFeature
| CatchFeature
); }
371 bool isStrictMode() const { return m_features
& StrictModeFeature
; }
372 ECMAMode
ecmaMode() const { return isStrictMode() ? StrictMode
: NotStrictMode
; }
374 void setNeverInline(bool value
) { m_neverInline
= value
; }
375 void setDidTryToEnterInLoop(bool value
) { m_didTryToEnterInLoop
= value
; }
376 bool neverInline() const { return m_neverInline
; }
377 bool didTryToEnterInLoop() const { return m_didTryToEnterInLoop
; }
378 bool isInliningCandidate() const { return !neverInline(); }
380 bool* addressOfDidTryToEnterInLoop() { return &m_didTryToEnterInLoop
; }
384 CodeFeatures
features() const { return m_features
; }
388 void recordParse(CodeFeatures features
, bool hasCapturedVariables
, int firstLine
, int lastLine
, unsigned startColumn
, unsigned endColumn
)
390 m_features
= features
;
391 m_hasCapturedVariables
= hasCapturedVariables
;
392 m_firstLine
= firstLine
;
393 m_lastLine
= lastLine
;
394 ASSERT(startColumn
!= UINT_MAX
);
395 m_startColumn
= startColumn
;
396 ASSERT(endColumn
!= UINT_MAX
);
397 m_endColumn
= endColumn
;
400 void installCode(CodeBlock
*);
401 RefPtr
<CodeBlock
> newCodeBlockFor(CodeSpecializationKind
, JSFunction
*, JSScope
*, JSObject
*& exception
);
402 PassRefPtr
<CodeBlock
> newReplacementCodeBlockFor(CodeSpecializationKind
);
404 JSObject
* prepareForExecution(ExecState
* exec
, JSFunction
* function
, JSScope
* scope
, CodeSpecializationKind kind
)
406 if (hasJITCodeFor(kind
))
408 return prepareForExecutionImpl(exec
, function
, scope
, kind
);
411 template <typename Functor
> void forEachCodeBlock(Functor
&&);
414 JSObject
* prepareForExecutionImpl(ExecState
*, JSFunction
*, JSScope
*, CodeSpecializationKind
);
417 ScriptExecutable(Structure
* structure
, VM
& vm
, const SourceCode
& source
, bool isInStrictContext
);
419 void finishCreation(VM
& vm
)
421 Base::finishCreation(vm
);
422 vm
.heap
.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
424 #if ENABLE(CODEBLOCK_SAMPLING)
425 if (SamplingTool
* sampler
= vm
.interpreter
->sampler())
426 sampler
->notifyOfScope(vm
, this);
431 CodeFeatures m_features
;
432 bool m_hasCapturedVariables
;
434 bool m_didTryToEnterInLoop
;
435 int m_overrideLineNumber
;
438 unsigned m_startColumn
;
439 unsigned m_endColumn
;
440 unsigned m_typeProfilingStartOffset
;
441 unsigned m_typeProfilingEndOffset
;
444 class EvalExecutable final
: public ScriptExecutable
{
445 friend class LLIntOffsetsExtractor
;
447 typedef ScriptExecutable Base
;
448 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
450 static void destroy(JSCell
*);
452 EvalCodeBlock
* codeBlock()
454 return m_evalCodeBlock
.get();
457 static EvalExecutable
* create(ExecState
*, const SourceCode
&, bool isInStrictContext
, ThisTDZMode
);
459 PassRefPtr
<JITCode
> generatedJITCode()
461 return generatedJITCodeForCall();
464 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
466 return Structure::create(vm
, globalObject
, proto
, TypeInfo(EvalExecutableType
, StructureFlags
), info());
475 ExecutableInfo
executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None
); }
477 unsigned numVariables() { return m_unlinkedEvalCodeBlock
->numVariables(); }
478 unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock
->numberOfFunctionDecls(); }
481 friend class ScriptExecutable
;
482 EvalExecutable(ExecState
*, const SourceCode
&, bool);
484 static void visitChildren(JSCell
*, SlotVisitor
&);
486 RefPtr
<EvalCodeBlock
> m_evalCodeBlock
;
487 WriteBarrier
<UnlinkedEvalCodeBlock
> m_unlinkedEvalCodeBlock
;
490 class ProgramExecutable final
: public ScriptExecutable
{
491 friend class LLIntOffsetsExtractor
;
493 typedef ScriptExecutable Base
;
494 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
496 static ProgramExecutable
* create(ExecState
* exec
, const SourceCode
& source
)
498 ProgramExecutable
* executable
= new (NotNull
, allocateCell
<ProgramExecutable
>(*exec
->heap())) ProgramExecutable(exec
, source
);
499 executable
->finishCreation(exec
->vm());
504 JSObject
* initializeGlobalProperties(VM
&, CallFrame
*, JSScope
*);
506 static void destroy(JSCell
*);
508 ProgramCodeBlock
* codeBlock()
510 return m_programCodeBlock
.get();
513 JSObject
* checkSyntax(ExecState
*);
515 PassRefPtr
<JITCode
> generatedJITCode()
517 return generatedJITCodeForCall();
520 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
522 return Structure::create(vm
, globalObject
, proto
, TypeInfo(ProgramExecutableType
, StructureFlags
), info());
531 ExecutableInfo
executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false, ConstructorKind::None
); }
534 friend class ScriptExecutable
;
536 ProgramExecutable(ExecState
*, const SourceCode
&);
538 static void visitChildren(JSCell
*, SlotVisitor
&);
540 WriteBarrier
<UnlinkedProgramCodeBlock
> m_unlinkedProgramCodeBlock
;
541 RefPtr
<ProgramCodeBlock
> m_programCodeBlock
;
544 class FunctionExecutable final
: public ScriptExecutable
{
546 friend class LLIntOffsetsExtractor
;
548 typedef ScriptExecutable Base
;
549 static const unsigned StructureFlags
= Base::StructureFlags
| StructureIsImmortal
;
551 static FunctionExecutable
* create(
552 VM
& vm
, const SourceCode
& source
, UnlinkedFunctionExecutable
* unlinkedExecutable
,
553 unsigned firstLine
, unsigned lastLine
, unsigned startColumn
, unsigned endColumn
)
555 FunctionExecutable
* executable
= new (NotNull
, allocateCell
<FunctionExecutable
>(vm
.heap
)) FunctionExecutable(vm
, source
, unlinkedExecutable
, firstLine
, lastLine
, startColumn
, endColumn
);
556 executable
->finishCreation(vm
);
559 static FunctionExecutable
* fromGlobalCode(
560 const Identifier
& name
, ExecState
&, const SourceCode
&,
561 JSObject
*& exception
, int overrideLineNumber
);
563 static void destroy(JSCell
*);
565 UnlinkedFunctionExecutable
* unlinkedExecutable()
567 return m_unlinkedExecutable
.get();
570 // Returns either call or construct bytecode. This can be appropriate
571 // for answering questions that that don't vary between call and construct --
572 // for example, argumentsRegister().
573 FunctionCodeBlock
* eitherCodeBlock()
575 if (m_codeBlockForCall
)
576 return m_codeBlockForCall
.get();
577 return m_codeBlockForConstruct
.get();
580 bool isGeneratedForCall() const
582 return m_codeBlockForCall
;
585 FunctionCodeBlock
* codeBlockForCall()
587 return m_codeBlockForCall
.get();
590 bool isGeneratedForConstruct() const
592 return m_codeBlockForConstruct
;
595 FunctionCodeBlock
* codeBlockForConstruct()
597 return m_codeBlockForConstruct
.get();
600 bool isGeneratedFor(CodeSpecializationKind kind
)
602 if (kind
== CodeForCall
)
603 return isGeneratedForCall();
604 ASSERT(kind
== CodeForConstruct
);
605 return isGeneratedForConstruct();
608 FunctionCodeBlock
* codeBlockFor(CodeSpecializationKind kind
)
610 if (kind
== CodeForCall
)
611 return codeBlockForCall();
612 ASSERT(kind
== CodeForConstruct
);
613 return codeBlockForConstruct();
616 FunctionCodeBlock
* baselineCodeBlockFor(CodeSpecializationKind
);
618 FunctionCodeBlock
* profiledCodeBlockFor(CodeSpecializationKind kind
)
620 return baselineCodeBlockFor(kind
);
623 RefPtr
<TypeSet
> returnStatementTypeSet()
625 if (!m_returnStatementTypeSet
)
626 m_returnStatementTypeSet
= TypeSet::create();
628 return m_returnStatementTypeSet
;
631 FunctionMode
functionMode() { return m_unlinkedExecutable
->functionMode(); }
632 bool isBuiltinFunction() const { return m_unlinkedExecutable
->isBuiltinFunction(); }
633 bool isClassConstructorFunction() const { return m_unlinkedExecutable
->isClassConstructorFunction(); }
634 const Identifier
& name() { return m_unlinkedExecutable
->name(); }
635 const Identifier
& inferredName() { return m_unlinkedExecutable
->inferredName(); }
636 JSString
* nameValue() const { return m_unlinkedExecutable
->nameValue(); }
637 size_t parameterCount() const { return m_unlinkedExecutable
->parameterCount(); } // Excluding 'this'!
638 SymbolTable
* symbolTable(CodeSpecializationKind
);
640 void clearUnlinkedCodeForRecompilation();
641 static void visitChildren(JSCell
*, SlotVisitor
&);
642 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
644 return Structure::create(vm
, globalObject
, proto
, TypeInfo(FunctionExecutableType
, StructureFlags
), info());
647 unsigned parametersStartOffset() const { return m_parametersStartOffset
; }
649 void overrideParameterAndTypeProfilingStartEndOffsets(unsigned parametersStartOffset
, unsigned typeProfilingStartOffset
, unsigned typeProfilingEndOffset
)
651 m_parametersStartOffset
= parametersStartOffset
;
652 m_typeProfilingStartOffset
= typeProfilingStartOffset
;
653 m_typeProfilingEndOffset
= typeProfilingEndOffset
;
662 InferredValue
* singletonFunction() { return m_singletonFunction
.get(); }
666 VM
&, const SourceCode
&, UnlinkedFunctionExecutable
*, unsigned firstLine
,
667 unsigned lastLine
, unsigned startColumn
, unsigned endColumn
);
669 void finishCreation(VM
&);
671 friend class ScriptExecutable
;
673 WriteBarrier
<UnlinkedFunctionExecutable
> m_unlinkedExecutable
;
674 RefPtr
<FunctionCodeBlock
> m_codeBlockForCall
;
675 RefPtr
<FunctionCodeBlock
> m_codeBlockForConstruct
;
676 RefPtr
<TypeSet
> m_returnStatementTypeSet
;
677 unsigned m_parametersStartOffset
;
678 WriteBarrier
<InferredValue
> m_singletonFunction
;
681 inline void ExecutableBase::clearCodeVirtual(ExecutableBase
* executable
)
683 switch (executable
->type()) {
684 case EvalExecutableType
:
685 return jsCast
<EvalExecutable
*>(executable
)->clearCode();
686 case ProgramExecutableType
:
687 return jsCast
<ProgramExecutable
*>(executable
)->clearCode();
688 case FunctionExecutableType
:
689 return jsCast
<FunctionExecutable
*>(executable
)->clearCode();
691 return jsCast
<NativeExecutable
*>(executable
)->clearCode();
695 inline void ScriptExecutable::unlinkCalls()
698 case EvalExecutableType
:
699 return jsCast
<EvalExecutable
*>(this)->unlinkCalls();
700 case ProgramExecutableType
:
701 return jsCast
<ProgramExecutable
*>(this)->unlinkCalls();
702 case FunctionExecutableType
:
703 return jsCast
<FunctionExecutable
*>(this)->unlinkCalls();
705 RELEASE_ASSERT_NOT_REACHED();