2 * Copyright (C) 2009, 2010, 2013 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 "JSFunction.h"
37 #include "Interpreter.h"
39 #include "JSGlobalObject.h"
40 #include "RegisterPreservationMode.h"
41 #include "SamplingTool.h"
42 #include "SourceCode.h"
43 #include "UnlinkedCodeBlock.h"
44 #include <wtf/PassOwnPtr.h>
51 class FunctionCodeBlock
;
52 class LLIntOffsetsExtractor
;
53 class ProgramCodeBlock
;
56 enum CompilationKind
{ FirstCompilation
, OptimizingCompilation
};
58 inline bool isCall(CodeSpecializationKind kind
)
60 if (kind
== CodeForCall
)
62 ASSERT(kind
== CodeForConstruct
);
66 class ExecutableBase
: public JSCell
, public DoublyLinkedListNode
<ExecutableBase
> {
67 friend class WTF::DoublyLinkedListNode
<ExecutableBase
>;
71 static const int NUM_PARAMETERS_IS_HOST
= 0;
72 static const int NUM_PARAMETERS_NOT_COMPILED
= -1;
74 ExecutableBase(VM
& vm
, Structure
* structure
, int numParameters
)
75 : JSCell(vm
, structure
)
76 , m_numParametersForCall(numParameters
)
77 , m_numParametersForConstruct(numParameters
)
81 void finishCreation(VM
& vm
)
83 Base::finishCreation(vm
);
90 static const bool needsDestruction
= true;
91 static const bool hasImmortalStructure
= true;
92 static void destroy(JSCell
*);
95 CodeBlockHash
hashFor(CodeSpecializationKind
) const;
97 bool isEvalExecutable()
99 return type() == EvalExecutableType
;
101 bool isFunctionExecutable()
103 return type() == FunctionExecutableType
;
105 bool isProgramExecutable()
107 return type() == ProgramExecutableType
;
110 bool isHostFunction() const
112 ASSERT((m_numParametersForCall
== NUM_PARAMETERS_IS_HOST
) == (m_numParametersForConstruct
== NUM_PARAMETERS_IS_HOST
));
113 return m_numParametersForCall
== NUM_PARAMETERS_IS_HOST
;
116 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(vm
, globalObject
, proto
, TypeInfo(CompoundType
, StructureFlags
), info()); }
123 static const unsigned StructureFlags
= StructureIsImmortal
;
124 int m_numParametersForCall
;
125 int m_numParametersForConstruct
;
128 static void clearCodeVirtual(ExecutableBase
*);
130 PassRefPtr
<JITCode
> generatedJITCodeForCall()
132 ASSERT(m_jitCodeForCall
);
133 return m_jitCodeForCall
;
136 PassRefPtr
<JITCode
> generatedJITCodeForConstruct()
138 ASSERT(m_jitCodeForConstruct
);
139 return m_jitCodeForConstruct
;
142 PassRefPtr
<JITCode
> generatedJITCodeFor(CodeSpecializationKind kind
)
144 if (kind
== CodeForCall
)
145 return generatedJITCodeForCall();
146 ASSERT(kind
== CodeForConstruct
);
147 return generatedJITCodeForConstruct();
150 MacroAssemblerCodePtr
entrypointFor(
151 VM
& vm
, CodeSpecializationKind kind
, ArityCheckMode arity
, RegisterPreservationMode registers
)
153 // Check if we have a cached result. We only have it for arity check because we use the
154 // no-arity entrypoint in non-virtual calls, which will "cache" this value directly in
156 if (arity
== MustCheckArity
) {
160 case RegisterPreservationNotRequired
:
161 if (MacroAssemblerCodePtr result
= m_jitCodeForCallWithArityCheck
)
164 case MustPreserveRegisters
:
165 if (MacroAssemblerCodePtr result
= m_jitCodeForCallWithArityCheckAndPreserveRegs
)
170 case CodeForConstruct
:
172 case RegisterPreservationNotRequired
:
173 if (MacroAssemblerCodePtr result
= m_jitCodeForConstructWithArityCheck
)
176 case MustPreserveRegisters
:
177 if (MacroAssemblerCodePtr result
= m_jitCodeForConstructWithArityCheckAndPreserveRegs
)
184 MacroAssemblerCodePtr result
=
185 generatedJITCodeFor(kind
)->addressForCall(vm
, this, arity
, registers
);
186 if (arity
== MustCheckArity
) {
187 // Cache the result; this is necessary for the JIT's virtual call optimizations.
191 case RegisterPreservationNotRequired
:
192 m_jitCodeForCallWithArityCheck
= result
;
194 case MustPreserveRegisters
:
195 m_jitCodeForCallWithArityCheckAndPreserveRegs
= result
;
199 case CodeForConstruct
:
201 case RegisterPreservationNotRequired
:
202 m_jitCodeForConstructWithArityCheck
= result
;
204 case MustPreserveRegisters
:
205 m_jitCodeForConstructWithArityCheckAndPreserveRegs
= result
;
214 static ptrdiff_t offsetOfJITCodeWithArityCheckFor(
215 CodeSpecializationKind kind
, RegisterPreservationMode registers
)
220 case RegisterPreservationNotRequired
:
221 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForCallWithArityCheck
);
222 case MustPreserveRegisters
:
223 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForCallWithArityCheckAndPreserveRegs
);
225 case CodeForConstruct
:
227 case RegisterPreservationNotRequired
:
228 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForConstructWithArityCheck
);
229 case MustPreserveRegisters
:
230 return OBJECT_OFFSETOF(ExecutableBase
, m_jitCodeForConstructWithArityCheckAndPreserveRegs
);
233 RELEASE_ASSERT_NOT_REACHED();
237 static ptrdiff_t offsetOfNumParametersFor(CodeSpecializationKind kind
)
239 if (kind
== CodeForCall
)
240 return OBJECT_OFFSETOF(ExecutableBase
, m_numParametersForCall
);
241 ASSERT(kind
== CodeForConstruct
);
242 return OBJECT_OFFSETOF(ExecutableBase
, m_numParametersForConstruct
);
245 bool hasJITCodeForCall() const
247 return m_numParametersForCall
>= 0;
250 bool hasJITCodeForConstruct() const
252 return m_numParametersForConstruct
>= 0;
255 bool hasJITCodeFor(CodeSpecializationKind kind
) const
257 if (kind
== CodeForCall
)
258 return hasJITCodeForCall();
259 ASSERT(kind
== CodeForConstruct
);
260 return hasJITCodeForConstruct();
263 // Intrinsics are only for calls, currently.
264 Intrinsic
intrinsic() const;
266 Intrinsic
intrinsicFor(CodeSpecializationKind kind
) const
273 void dump(PrintStream
&) const;
276 ExecutableBase
* m_prev
;
277 ExecutableBase
* m_next
;
279 RefPtr
<JITCode
> m_jitCodeForCall
;
280 RefPtr
<JITCode
> m_jitCodeForConstruct
;
281 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheck
;
282 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheck
;
283 MacroAssemblerCodePtr m_jitCodeForCallWithArityCheckAndPreserveRegs
;
284 MacroAssemblerCodePtr m_jitCodeForConstructWithArityCheckAndPreserveRegs
;
287 class NativeExecutable
: public ExecutableBase
{
289 friend class LLIntOffsetsExtractor
;
291 typedef ExecutableBase Base
;
293 static NativeExecutable
* create(VM
& vm
, PassRefPtr
<JITCode
> callThunk
, NativeFunction function
, PassRefPtr
<JITCode
> constructThunk
, NativeFunction constructor
, Intrinsic intrinsic
)
295 NativeExecutable
* executable
;
296 executable
= new (NotNull
, allocateCell
<NativeExecutable
>(vm
.heap
)) NativeExecutable(vm
, function
, constructor
);
297 executable
->finishCreation(vm
, callThunk
, constructThunk
, intrinsic
);
302 static void destroy(JSCell
*);
305 CodeBlockHash
hashFor(CodeSpecializationKind
) const;
307 NativeFunction
function() { return m_function
; }
308 NativeFunction
constructor() { return m_constructor
; }
310 NativeFunction
nativeFunctionFor(CodeSpecializationKind kind
)
312 if (kind
== CodeForCall
)
314 ASSERT(kind
== CodeForConstruct
);
315 return constructor();
318 static ptrdiff_t offsetOfNativeFunctionFor(CodeSpecializationKind kind
)
320 if (kind
== CodeForCall
)
321 return OBJECT_OFFSETOF(NativeExecutable
, m_function
);
322 ASSERT(kind
== CodeForConstruct
);
323 return OBJECT_OFFSETOF(NativeExecutable
, m_constructor
);
326 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
) { return Structure::create(vm
, globalObject
, proto
, TypeInfo(LeafType
, StructureFlags
), info()); }
330 Intrinsic
intrinsic() const;
333 void finishCreation(VM
& vm
, PassRefPtr
<JITCode
> callThunk
, PassRefPtr
<JITCode
> constructThunk
, Intrinsic intrinsic
)
335 Base::finishCreation(vm
);
336 m_jitCodeForCall
= callThunk
;
337 m_jitCodeForConstruct
= constructThunk
;
338 m_intrinsic
= intrinsic
;
342 NativeExecutable(VM
& vm
, NativeFunction function
, NativeFunction constructor
)
343 : ExecutableBase(vm
, vm
.nativeExecutableStructure
.get(), NUM_PARAMETERS_IS_HOST
)
344 , m_function(function
)
345 , m_constructor(constructor
)
349 NativeFunction m_function
;
350 NativeFunction m_constructor
;
352 Intrinsic m_intrinsic
;
355 class ScriptExecutable
: public ExecutableBase
{
357 typedef ExecutableBase Base
;
359 ScriptExecutable(Structure
* structure
, VM
& vm
, const SourceCode
& source
, bool isInStrictContext
)
360 : ExecutableBase(vm
, structure
, NUM_PARAMETERS_NOT_COMPILED
)
362 , m_features(isInStrictContext
? StrictModeFeature
: 0)
363 , m_neverInline(false)
364 , m_startColumn(UINT_MAX
)
365 , m_endColumn(UINT_MAX
)
369 ScriptExecutable(Structure
* structure
, ExecState
* exec
, const SourceCode
& source
, bool isInStrictContext
)
370 : ExecutableBase(exec
->vm(), structure
, NUM_PARAMETERS_NOT_COMPILED
)
372 , m_features(isInStrictContext
? StrictModeFeature
: 0)
373 , m_neverInline(false)
374 , m_startColumn(UINT_MAX
)
375 , m_endColumn(UINT_MAX
)
380 static void destroy(JSCell
*);
383 CodeBlockHash
hashFor(CodeSpecializationKind
) const;
385 const SourceCode
& source() const { return m_source
; }
386 intptr_t sourceID() const { return m_source
.providerID(); }
387 const String
& sourceURL() const { return m_source
.provider()->url(); }
388 int lineNo() const { return m_firstLine
; }
389 int lastLine() const { return m_lastLine
; }
390 unsigned startColumn() const { return m_startColumn
; }
391 unsigned endColumn() const { return m_endColumn
; }
393 bool usesEval() const { return m_features
& EvalFeature
; }
394 bool usesArguments() const { return m_features
& ArgumentsFeature
; }
395 bool needsActivation() const { return m_hasCapturedVariables
|| m_features
& (EvalFeature
| WithFeature
| CatchFeature
); }
396 bool isStrictMode() const { return m_features
& StrictModeFeature
; }
397 ECMAMode
ecmaMode() const { return isStrictMode() ? StrictMode
: NotStrictMode
; }
399 void setNeverInline(bool value
) { m_neverInline
= value
; }
400 bool neverInline() const { return m_neverInline
; }
401 bool isInliningCandidate() const { return !neverInline(); }
405 CodeFeatures
features() const { return m_features
; }
409 void recordParse(CodeFeatures features
, bool hasCapturedVariables
, int firstLine
, int lastLine
, unsigned startColumn
, unsigned endColumn
)
411 m_features
= features
;
412 m_hasCapturedVariables
= hasCapturedVariables
;
413 m_firstLine
= firstLine
;
414 m_lastLine
= lastLine
;
415 ASSERT(startColumn
!= UINT_MAX
);
416 m_startColumn
= startColumn
;
417 ASSERT(endColumn
!= UINT_MAX
);
418 m_endColumn
= endColumn
;
421 void installCode(CodeBlock
*);
422 PassRefPtr
<CodeBlock
> newCodeBlockFor(CodeSpecializationKind
, JSFunction
*, JSScope
**, JSObject
*& exception
);
423 PassRefPtr
<CodeBlock
> newReplacementCodeBlockFor(CodeSpecializationKind
);
425 JSObject
* prepareForExecution(ExecState
* exec
, JSFunction
* function
, JSScope
** scope
, CodeSpecializationKind kind
)
427 if (hasJITCodeFor(kind
))
429 return prepareForExecutionImpl(exec
, function
, scope
, kind
);
432 template <typename Functor
> void forEachCodeBlock(Functor
&&);
435 JSObject
* prepareForExecutionImpl(ExecState
*, JSFunction
*, JSScope
**, CodeSpecializationKind
);
438 void finishCreation(VM
& vm
)
440 Base::finishCreation(vm
);
441 vm
.heap
.addCompiledCode(this); // Balanced by Heap::deleteUnmarkedCompiledCode().
443 #if ENABLE(CODEBLOCK_SAMPLING)
444 if (SamplingTool
* sampler
= vm
.interpreter
->sampler())
445 sampler
->notifyOfScope(vm
, this);
450 CodeFeatures m_features
;
451 bool m_hasCapturedVariables
;
455 unsigned m_startColumn
;
456 unsigned m_endColumn
;
459 class EvalExecutable
: public ScriptExecutable
{
460 friend class LLIntOffsetsExtractor
;
462 typedef ScriptExecutable Base
;
464 static void destroy(JSCell
*);
466 EvalCodeBlock
* codeBlock()
468 return m_evalCodeBlock
.get();
471 static EvalExecutable
* create(ExecState
*, const SourceCode
&, bool isInStrictContext
);
473 PassRefPtr
<JITCode
> generatedJITCode()
475 return generatedJITCodeForCall();
478 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
480 return Structure::create(vm
, globalObject
, proto
, TypeInfo(EvalExecutableType
, StructureFlags
), info());
489 ExecutableInfo
executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false); }
491 unsigned numVariables() { return m_unlinkedEvalCodeBlock
->numVariables(); }
492 unsigned numberOfFunctionDecls() { return m_unlinkedEvalCodeBlock
->numberOfFunctionDecls(); }
495 friend class ScriptExecutable
;
496 static const unsigned StructureFlags
= OverridesVisitChildren
| ScriptExecutable::StructureFlags
;
497 EvalExecutable(ExecState
*, const SourceCode
&, bool);
499 static void visitChildren(JSCell
*, SlotVisitor
&);
501 RefPtr
<EvalCodeBlock
> m_evalCodeBlock
;
502 WriteBarrier
<UnlinkedEvalCodeBlock
> m_unlinkedEvalCodeBlock
;
505 class ProgramExecutable
: public ScriptExecutable
{
506 friend class LLIntOffsetsExtractor
;
508 typedef ScriptExecutable Base
;
510 static ProgramExecutable
* create(ExecState
* exec
, const SourceCode
& source
)
512 ProgramExecutable
* executable
= new (NotNull
, allocateCell
<ProgramExecutable
>(*exec
->heap())) ProgramExecutable(exec
, source
);
513 executable
->finishCreation(exec
->vm());
518 JSObject
* initializeGlobalProperties(VM
&, CallFrame
*, JSScope
*);
520 static void destroy(JSCell
*);
522 ProgramCodeBlock
* codeBlock()
524 return m_programCodeBlock
.get();
527 JSObject
* checkSyntax(ExecState
*);
529 PassRefPtr
<JITCode
> generatedJITCode()
531 return generatedJITCodeForCall();
534 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
536 return Structure::create(vm
, globalObject
, proto
, TypeInfo(ProgramExecutableType
, StructureFlags
), info());
545 ExecutableInfo
executableInfo() const { return ExecutableInfo(needsActivation(), usesEval(), isStrictMode(), false, false); }
548 friend class ScriptExecutable
;
550 static const unsigned StructureFlags
= OverridesVisitChildren
| ScriptExecutable::StructureFlags
;
552 ProgramExecutable(ExecState
*, const SourceCode
&);
554 static void visitChildren(JSCell
*, SlotVisitor
&);
556 WriteBarrier
<UnlinkedProgramCodeBlock
> m_unlinkedProgramCodeBlock
;
557 RefPtr
<ProgramCodeBlock
> m_programCodeBlock
;
560 class FunctionExecutable
: public ScriptExecutable
{
562 friend class LLIntOffsetsExtractor
;
564 typedef ScriptExecutable Base
;
566 static FunctionExecutable
* create(VM
& vm
, const SourceCode
& source
, UnlinkedFunctionExecutable
* unlinkedExecutable
, unsigned firstLine
, unsigned lastLine
, unsigned startColumn
, unsigned endColumn
, bool bodyIncludesBraces
= true)
568 FunctionExecutable
* executable
= new (NotNull
, allocateCell
<FunctionExecutable
>(vm
.heap
)) FunctionExecutable(vm
, source
, unlinkedExecutable
, firstLine
, lastLine
, startColumn
, endColumn
, bodyIncludesBraces
);
569 executable
->finishCreation(vm
);
572 static FunctionExecutable
* fromGlobalCode(const Identifier
& name
, ExecState
*, Debugger
*, const SourceCode
&, JSObject
** exception
);
574 static void destroy(JSCell
*);
576 UnlinkedFunctionExecutable
* unlinkedExecutable()
578 return m_unlinkedExecutable
.get();
581 // Returns either call or construct bytecode. This can be appropriate
582 // for answering questions that that don't vary between call and construct --
583 // for example, argumentsRegister().
584 FunctionCodeBlock
* eitherCodeBlock()
586 if (m_codeBlockForCall
)
587 return m_codeBlockForCall
.get();
588 return m_codeBlockForConstruct
.get();
591 bool isGeneratedForCall() const
593 return m_codeBlockForCall
;
596 FunctionCodeBlock
* codeBlockForCall()
598 return m_codeBlockForCall
.get();
601 bool isGeneratedForConstruct() const
603 return m_codeBlockForConstruct
;
606 FunctionCodeBlock
* codeBlockForConstruct()
608 return m_codeBlockForConstruct
.get();
611 bool isGeneratedFor(CodeSpecializationKind kind
)
613 if (kind
== CodeForCall
)
614 return isGeneratedForCall();
615 ASSERT(kind
== CodeForConstruct
);
616 return isGeneratedForConstruct();
619 FunctionCodeBlock
* codeBlockFor(CodeSpecializationKind kind
)
621 if (kind
== CodeForCall
)
622 return codeBlockForCall();
623 ASSERT(kind
== CodeForConstruct
);
624 return codeBlockForConstruct();
627 FunctionCodeBlock
* baselineCodeBlockFor(CodeSpecializationKind
);
629 FunctionCodeBlock
* profiledCodeBlockFor(CodeSpecializationKind kind
)
631 return baselineCodeBlockFor(kind
);
634 FunctionMode
functionMode() { return m_unlinkedExecutable
->functionMode(); }
635 bool isBuiltinFunction() const { return m_unlinkedExecutable
->isBuiltinFunction(); }
636 const Identifier
& name() { return m_unlinkedExecutable
->name(); }
637 const Identifier
& inferredName() { return m_unlinkedExecutable
->inferredName(); }
638 JSString
* nameValue() const { return m_unlinkedExecutable
->nameValue(); }
639 size_t parameterCount() const { return m_unlinkedExecutable
->parameterCount(); } // Excluding 'this'!
640 String
paramString() const;
641 SymbolTable
* symbolTable(CodeSpecializationKind
);
643 void clearCodeIfNotCompiling();
644 void clearUnlinkedCodeForRecompilationIfNotCompiling();
645 static void visitChildren(JSCell
*, SlotVisitor
&);
646 static Structure
* createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue proto
)
648 return Structure::create(vm
, globalObject
, proto
, TypeInfo(FunctionExecutableType
, StructureFlags
), info());
657 bool bodyIncludesBraces() const { return m_bodyIncludesBraces
; }
660 FunctionExecutable(VM
&, const SourceCode
&, UnlinkedFunctionExecutable
*, unsigned firstLine
, unsigned lastLine
, unsigned startColumn
, unsigned endColumn
, bool bodyIncludesBraces
);
665 if (!m_jitCodeForCall
&& m_codeBlockForCall
)
667 if (!m_jitCodeForConstruct
&& m_codeBlockForConstruct
)
673 friend class ScriptExecutable
;
675 static const unsigned StructureFlags
= OverridesVisitChildren
| ScriptExecutable::StructureFlags
;
676 WriteBarrier
<UnlinkedFunctionExecutable
> m_unlinkedExecutable
;
677 RefPtr
<FunctionCodeBlock
> m_codeBlockForCall
;
678 RefPtr
<FunctionCodeBlock
> m_codeBlockForConstruct
;
679 bool m_bodyIncludesBraces
;
680 bool m_didParseForTheFirstTime
;
683 inline void ExecutableBase::clearCodeVirtual(ExecutableBase
* executable
)
685 switch (executable
->type()) {
686 case EvalExecutableType
:
687 return jsCast
<EvalExecutable
*>(executable
)->clearCode();
688 case ProgramExecutableType
:
689 return jsCast
<ProgramExecutable
*>(executable
)->clearCode();
690 case FunctionExecutableType
:
691 return jsCast
<FunctionExecutable
*>(executable
)->clearCode();
693 return jsCast
<NativeExecutable
*>(executable
)->clearCode();
697 inline void ScriptExecutable::unlinkCalls()
700 case EvalExecutableType
:
701 return jsCast
<EvalExecutable
*>(this)->unlinkCalls();
702 case ProgramExecutableType
:
703 return jsCast
<ProgramExecutable
*>(this)->unlinkCalls();
704 case FunctionExecutableType
:
705 return jsCast
<FunctionExecutable
*>(this)->unlinkCalls();
707 RELEASE_ASSERT_NOT_REACHED();