JavascriptNativeOperators.h 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js
  7. {
  8. #if ENABLE_NATIVE_CODEGEN
  9. template <typename T>
  10. class BranchDictionaryWrapper
  11. {
  12. public:
  13. class DictAllocator :public NativeCodeData::Allocator
  14. {
  15. public:
  16. char * Alloc(size_t requestedBytes)
  17. {
  18. char* dataBlock = __super::Alloc(requestedBytes);
  19. #if DBG
  20. if (JITManager::GetJITManager()->IsJITServer())
  21. {
  22. NativeCodeData::DataChunk* chunk = NativeCodeData::GetDataChunk(dataBlock);
  23. chunk->dataType = "BranchDictionary::Bucket";
  24. if (PHASE_TRACE1(Js::NativeCodeDataPhase))
  25. {
  26. Output::Print(_u("NativeCodeData BranchDictionary::Bucket: chunk: %p, data: %p, index: %d, len: %x, totalOffset: %x, type: %S\n"),
  27. chunk, (void*)dataBlock, chunk->allocIndex, chunk->len, chunk->offset, chunk->dataType);
  28. }
  29. }
  30. #endif
  31. return dataBlock;
  32. }
  33. char * AllocZero(size_t requestedBytes)
  34. {
  35. char* dataBlock = __super::AllocZero(requestedBytes);
  36. #if DBG
  37. if (JITManager::GetJITManager()->IsJITServer())
  38. {
  39. NativeCodeData::DataChunk* chunk = NativeCodeData::GetDataChunk(dataBlock);
  40. chunk->dataType = "BranchDictionary::Entries";
  41. if (PHASE_TRACE1(Js::NativeCodeDataPhase))
  42. {
  43. Output::Print(_u("NativeCodeData BranchDictionary::Entries: chunk: %p, data: %p, index: %d, len: %x, totalOffset: %x, type: %S\n"),
  44. chunk, (void*)dataBlock, chunk->allocIndex, chunk->len, chunk->offset, chunk->dataType);
  45. }
  46. }
  47. #endif
  48. return dataBlock;
  49. }
  50. };
  51. template <class TKey, class TValue>
  52. class SimpleDictionaryEntryWithFixUp : public JsUtil::SimpleDictionaryEntry<TKey, TValue>
  53. {
  54. public:
  55. void FixupWithRemoteKey(void* remoteKey)
  56. {
  57. this->key = (TKey)remoteKey;
  58. }
  59. };
  60. typedef JsUtil::BaseDictionary<T, void*, DictAllocator, PowerOf2SizePolicy, DefaultComparer, SimpleDictionaryEntryWithFixUp> BranchBaseDictionary;
  61. class BranchDictionary :public BranchBaseDictionary
  62. {
  63. public:
  64. BranchDictionary(DictAllocator* allocator, uint dictionarySize)
  65. : BranchBaseDictionary(allocator, dictionarySize)
  66. {
  67. }
  68. void Fixup(NativeCodeData::DataChunk* chunkList, void** remoteKeys)
  69. {
  70. for (int i = 0; i < this->Count(); i++)
  71. {
  72. this->entries[i].FixupWithRemoteKey(remoteKeys[i]);
  73. }
  74. FixupNativeDataPointer(buckets, chunkList);
  75. FixupNativeDataPointer(entries, chunkList);
  76. }
  77. };
  78. BranchDictionaryWrapper(NativeCodeData::Allocator * allocator, uint dictionarySize, ArenaAllocator* remoteKeyAlloc) :
  79. defaultTarget(nullptr), dictionary((DictAllocator*)allocator, dictionarySize)
  80. {
  81. if (remoteKeyAlloc)
  82. {
  83. remoteKeys = AnewArrayZ(remoteKeyAlloc, void*, dictionarySize);
  84. }
  85. else
  86. {
  87. Assert(!JITManager::GetJITManager()->IsJITServer());
  88. remoteKeys = nullptr;
  89. }
  90. }
  91. BranchDictionary dictionary;
  92. void* defaultTarget;
  93. void** remoteKeys;
  94. static BranchDictionaryWrapper* New(NativeCodeData::Allocator * allocator, uint dictionarySize, ArenaAllocator* remoteKeyAlloc)
  95. {
  96. return NativeCodeDataNew(allocator, BranchDictionaryWrapper, allocator, dictionarySize, remoteKeyAlloc);
  97. }
  98. void AddEntry(uint32 offset, T key, void* remoteVar)
  99. {
  100. int index = dictionary.AddNew(key, (void**)offset);
  101. if (JITManager::GetJITManager()->IsJITServer())
  102. {
  103. Assert(remoteKeys);
  104. remoteKeys[index] = remoteVar;
  105. }
  106. }
  107. void Fixup(NativeCodeData::DataChunk* chunkList)
  108. {
  109. if (JITManager::GetJITManager()->IsJITServer())
  110. {
  111. dictionary.Fixup(chunkList, remoteKeys);
  112. }
  113. }
  114. };
  115. class JavascriptNativeOperators
  116. {
  117. public:
  118. static void * Op_SwitchStringLookUp(JavascriptString* str, Js::BranchDictionaryWrapper<Js::JavascriptString*>* stringDictionary, uintptr_t funcStart, uintptr_t funcEnd);
  119. #if ENABLE_DEBUG_CONFIG_OPTIONS
  120. static void TracePropertyEquivalenceCheck(const JitEquivalentTypeGuard* guard, const Type* type, const Type* refType, bool isEquivalent, uint failedPropertyIndex);
  121. #endif
  122. static bool CheckIfTypeIsEquivalent(Type* type, JitEquivalentTypeGuard* guard);
  123. static bool CheckIfTypeIsEquivalentForFixedField(Type* type, JitEquivalentTypeGuard* guard);
  124. static bool CheckIfPolyTypeIsEquivalent(Type* type, JitPolyEquivalentTypeGuard* guard, uint8 index);
  125. static bool CheckIfPolyTypeIsEquivalentForFixedField(Type* type, JitPolyEquivalentTypeGuard* guard, uint8 index);
  126. static bool EquivalenceCheckHelper(Type* type, JitEquivalentTypeGuard* guard, intptr_t value);
  127. static Var OP_GetElementI_JIT_ExpectingNativeFloatArray(Var instance, Var index, ScriptContext *scriptContext);
  128. static Var OP_GetElementI_JIT_ExpectingVarArray(Var instance, Var index, ScriptContext *scriptContext);
  129. static Var OP_GetElementI_UInt32_ExpectingNativeFloatArray(Var instance, uint32 aElementIndex, ScriptContext* scriptContext);
  130. static Var OP_GetElementI_UInt32_ExpectingVarArray(Var instance, uint32 aElementIndex, ScriptContext* scriptContext);
  131. static Var OP_GetElementI_Int32_ExpectingNativeFloatArray(Var instance, int32 aElementIndex, ScriptContext* scriptContext);
  132. static Var OP_GetElementI_Int32_ExpectingVarArray(Var instance, int32 aElementIndex, ScriptContext* scriptContext);
  133. #if DBG
  134. static void IntRangeCheckFailure();
  135. #endif
  136. private:
  137. static bool IsStaticTypeObjTypeSpecEquivalent(const TypeEquivalenceRecord& equivalenceRecord, uint& failedIndex);
  138. static bool IsStaticTypeObjTypeSpecEquivalent(const EquivalentPropertyEntry *entry);
  139. };
  140. #endif
  141. };