mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2024-11-26 21:50:53 +00:00
276 lines
8.2 KiB
C++
276 lines
8.2 KiB
C++
/*
|
|
* Copyright (C) 2012-2018 Apple Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "CacheableIdentifier.h"
|
|
#include "ClassInfo.h"
|
|
#include "CodeLocation.h"
|
|
#include "IndexingType.h"
|
|
#include "JITStubRoutine.h"
|
|
#include "Structure.h"
|
|
|
|
namespace JSC {
|
|
|
|
class Symbol;
|
|
|
|
#if ENABLE(JIT)
|
|
|
|
class ArrayProfile;
|
|
class StructureStubInfo;
|
|
|
|
enum JITArrayMode : uint8_t {
|
|
JITInt32,
|
|
JITDouble,
|
|
JITContiguous,
|
|
JITArrayStorage,
|
|
JITDirectArguments,
|
|
JITScopedArguments,
|
|
JITInt8Array,
|
|
JITInt16Array,
|
|
JITInt32Array,
|
|
JITUint8Array,
|
|
JITUint8ClampedArray,
|
|
JITUint16Array,
|
|
JITUint32Array,
|
|
JITFloat32Array,
|
|
JITFloat64Array
|
|
};
|
|
|
|
inline bool isOptimizableIndexingType(IndexingType indexingType)
|
|
{
|
|
switch (indexingType) {
|
|
case ALL_INT32_INDEXING_TYPES:
|
|
case ALL_DOUBLE_INDEXING_TYPES:
|
|
case ALL_CONTIGUOUS_INDEXING_TYPES:
|
|
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
inline bool hasOptimizableIndexingForJSType(JSType type)
|
|
{
|
|
switch (type) {
|
|
case DirectArgumentsType:
|
|
case ScopedArgumentsType:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
|
|
{
|
|
return isTypedView(classInfo->typedArrayStorageType);
|
|
}
|
|
|
|
inline bool hasOptimizableIndexing(Structure* structure)
|
|
{
|
|
return isOptimizableIndexingType(structure->indexingType())
|
|
|| hasOptimizableIndexingForJSType(structure->typeInfo().type())
|
|
|| hasOptimizableIndexingForClassInfo(structure->classInfo());
|
|
}
|
|
|
|
inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType)
|
|
{
|
|
switch (indexingType) {
|
|
case ALL_INT32_INDEXING_TYPES:
|
|
return JITInt32;
|
|
case ALL_DOUBLE_INDEXING_TYPES:
|
|
return JITDouble;
|
|
case ALL_CONTIGUOUS_INDEXING_TYPES:
|
|
return JITContiguous;
|
|
case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES:
|
|
return JITArrayStorage;
|
|
default:
|
|
CRASH();
|
|
return JITContiguous;
|
|
}
|
|
}
|
|
|
|
inline JITArrayMode jitArrayModeForJSType(JSType type)
|
|
{
|
|
switch (type) {
|
|
case DirectArgumentsType:
|
|
return JITDirectArguments;
|
|
case ScopedArgumentsType:
|
|
return JITScopedArguments;
|
|
default:
|
|
RELEASE_ASSERT_NOT_REACHED();
|
|
return JITContiguous;
|
|
}
|
|
}
|
|
|
|
inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo)
|
|
{
|
|
switch (classInfo->typedArrayStorageType) {
|
|
case TypeInt8:
|
|
return JITInt8Array;
|
|
case TypeInt16:
|
|
return JITInt16Array;
|
|
case TypeInt32:
|
|
return JITInt32Array;
|
|
case TypeUint8:
|
|
return JITUint8Array;
|
|
case TypeUint8Clamped:
|
|
return JITUint8ClampedArray;
|
|
case TypeUint16:
|
|
return JITUint16Array;
|
|
case TypeUint32:
|
|
return JITUint32Array;
|
|
case TypeFloat32:
|
|
return JITFloat32Array;
|
|
case TypeFloat64:
|
|
return JITFloat64Array;
|
|
default:
|
|
CRASH();
|
|
return JITContiguous;
|
|
}
|
|
}
|
|
|
|
inline bool jitArrayModePermitsPut(JITArrayMode mode)
|
|
{
|
|
switch (mode) {
|
|
case JITDirectArguments:
|
|
case JITScopedArguments:
|
|
// We could support put_by_val on these at some point, but it's just not that profitable
|
|
// at the moment.
|
|
return false;
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
|
|
inline bool jitArrayModePermitsPutDirect(JITArrayMode mode)
|
|
{
|
|
// We don't allow typed array putDirect here since putDirect has
|
|
// defineOwnProperty({configurable: true, writable:true, enumerable:true})
|
|
// semantics. Typed array indexed properties are non-configurable by
|
|
// default, so we can't simply store to a typed array for putDirect.
|
|
//
|
|
// We could model putDirect on ScopedArguments and DirectArguments, but we
|
|
// haven't found any performance incentive to do it yet.
|
|
switch (mode) {
|
|
case JITInt32:
|
|
case JITDouble:
|
|
case JITContiguous:
|
|
case JITArrayStorage:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
|
|
{
|
|
switch (mode) {
|
|
case JITInt8Array:
|
|
return TypeInt8;
|
|
case JITInt16Array:
|
|
return TypeInt16;
|
|
case JITInt32Array:
|
|
return TypeInt32;
|
|
case JITUint8Array:
|
|
return TypeUint8;
|
|
case JITUint8ClampedArray:
|
|
return TypeUint8Clamped;
|
|
case JITUint16Array:
|
|
return TypeUint16;
|
|
case JITUint32Array:
|
|
return TypeUint32;
|
|
case JITFloat32Array:
|
|
return TypeFloat32;
|
|
case JITFloat64Array:
|
|
return TypeFloat64;
|
|
default:
|
|
CRASH();
|
|
return NotTypedArray;
|
|
}
|
|
}
|
|
|
|
inline JITArrayMode jitArrayModeForStructure(Structure* structure)
|
|
{
|
|
if (isOptimizableIndexingType(structure->indexingType()))
|
|
return jitArrayModeForIndexingType(structure->indexingType());
|
|
|
|
if (hasOptimizableIndexingForJSType(structure->typeInfo().type()))
|
|
return jitArrayModeForJSType(structure->typeInfo().type());
|
|
|
|
ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo()));
|
|
return jitArrayModeForClassInfo(structure->classInfo());
|
|
}
|
|
|
|
struct ByValInfo {
|
|
ByValInfo(BytecodeIndex bytecodeIndex)
|
|
: bytecodeIndex(bytecodeIndex)
|
|
{
|
|
}
|
|
|
|
void setUp(CodeLocationJump<JSInternalPtrTag> notIndexJump, CodeLocationJump<JSInternalPtrTag> badTypeJump, CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler, JITArrayMode arrayMode, ArrayProfile* arrayProfile, CodeLocationLabel<JSInternalPtrTag> doneTarget, CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget, CodeLocationLabel<JSInternalPtrTag> slowPathTarget)
|
|
{
|
|
this->notIndexJump = notIndexJump;
|
|
this->badTypeJump = badTypeJump;
|
|
this->exceptionHandler = exceptionHandler;
|
|
this->doneTarget = doneTarget;
|
|
this->badTypeNextHotPathTarget = badTypeNextHotPathTarget;
|
|
this->slowPathTarget = slowPathTarget;
|
|
this->arrayProfile = arrayProfile;
|
|
this->slowPathCount = 0;
|
|
this->stubInfo = nullptr;
|
|
this->arrayMode = arrayMode;
|
|
this->tookSlowPath = false;
|
|
this->seen = false;
|
|
}
|
|
|
|
void visitAggregate(SlotVisitor&);
|
|
|
|
CodeLocationJump<JSInternalPtrTag> notIndexJump;
|
|
CodeLocationJump<JSInternalPtrTag> badTypeJump;
|
|
CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler;
|
|
CodeLocationLabel<JSInternalPtrTag> doneTarget;
|
|
CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget;
|
|
CodeLocationLabel<JSInternalPtrTag> slowPathTarget;
|
|
ArrayProfile* arrayProfile;
|
|
BytecodeIndex bytecodeIndex;
|
|
unsigned slowPathCount;
|
|
RefPtr<JITStubRoutine> stubRoutine;
|
|
CacheableIdentifier cachedId; // Once we set cachedId, we must not change the value. JIT code relies on that configured cachedId is marked and retained by CodeBlock through ByValInfo.
|
|
StructureStubInfo* stubInfo;
|
|
JITArrayMode arrayMode; // The array mode that was baked into the inline JIT code.
|
|
bool tookSlowPath : 1;
|
|
bool seen : 1;
|
|
};
|
|
|
|
inline BytecodeIndex getByValInfoBytecodeIndex(ByValInfo* info)
|
|
{
|
|
return info->bytecodeIndex;
|
|
}
|
|
|
|
#endif // ENABLE(JIT)
|
|
|
|
} // namespace JSC
|