bool AutoSystemInfo::IsCFGEnabled() { #if defined(_CONTROL_FLOW_GUARD) return true #ifdef ENABLE_DEBUG_CONFIG_OPTIONS && IsWinThresholdOrLater() && !PHASE_OFF1(Js::CFGPhase) #endif //ENABLE_DEBUG_CONFIG_OPTIONS ; #else return false; #endif //_CONTROL_FLOW_GUARD }
bool SharedArrayBuffer::IsValidVirtualBufferLength(uint length) const { #if ENABLE_FAST_ARRAYBUFFER /* 1. length >= 2^16 2. length is power of 2 or (length > 2^24 and length is multiple of 2^24) 3. length is a multiple of 4K */ return !PHASE_OFF1(Js::TypedArrayVirtualPhase) && JavascriptArrayBuffer::IsValidAsmJsBufferLengthAlgo(length, true); #else return false; #endif }
bool JavascriptSharedArrayBuffer::IsValidVirtualBufferLength(uint length) { #if _WIN64 /* 1. length >= 2^16 2. length is power of 2 or (length > 2^24 and length is multiple of 2^24) 3. length is a multiple of 4K */ return (!PHASE_OFF1(Js::TypedArrayVirtualPhase) && (length >= 0x10000) && (((length & (~length + 1)) == length) || (length >= 0x1000000 && ((length & 0xFFFFFF) == 0) ) ) && ((length % AutoSystemInfo::PageSize) == 0) ); #else return false; #endif }
bool DynamicTypeHandler::IsFixedDataProperty(FixedPropertyKind fixedPropKind) { return ((fixedPropKind & Js::FixedPropertyKind::FixedDataProperty) == Js::FixedPropertyKind::FixedDataProperty) && !PHASE_OFF1(UseFixedDataPropsPhase); }
bool InliningDecider::GetBuiltInInfoCommon( uint localFuncId, Js::OpCode *const inlineCandidateOpCode, ValueType *const returnType ) { // TODO: consider adding another column to JavascriptBuiltInFunctionList.h/LibraryFunction.h // and getting helper method from there instead of multiple switch labels. And for return value types too. switch (localFuncId) { case Js::JavascriptBuiltInFunction::Math_Abs: *inlineCandidateOpCode = Js::OpCode::InlineMathAbs; break; case Js::JavascriptBuiltInFunction::Math_Acos: *inlineCandidateOpCode = Js::OpCode::InlineMathAcos; break; case Js::JavascriptBuiltInFunction::Math_Asin: *inlineCandidateOpCode = Js::OpCode::InlineMathAsin; break; case Js::JavascriptBuiltInFunction::Math_Atan: *inlineCandidateOpCode = Js::OpCode::InlineMathAtan; break; case Js::JavascriptBuiltInFunction::Math_Atan2: *inlineCandidateOpCode = Js::OpCode::InlineMathAtan2; break; case Js::JavascriptBuiltInFunction::Math_Cos: *inlineCandidateOpCode = Js::OpCode::InlineMathCos; break; case Js::JavascriptBuiltInFunction::Math_Exp: *inlineCandidateOpCode = Js::OpCode::InlineMathExp; break; case Js::JavascriptBuiltInFunction::Math_Log: *inlineCandidateOpCode = Js::OpCode::InlineMathLog; break; case Js::JavascriptBuiltInFunction::Math_Pow: *inlineCandidateOpCode = Js::OpCode::InlineMathPow; break; case Js::JavascriptBuiltInFunction::Math_Sin: *inlineCandidateOpCode = Js::OpCode::InlineMathSin; break; case Js::JavascriptBuiltInFunction::Math_Sqrt: *inlineCandidateOpCode = Js::OpCode::InlineMathSqrt; break; case Js::JavascriptBuiltInFunction::Math_Tan: *inlineCandidateOpCode = Js::OpCode::InlineMathTan; break; case Js::JavascriptBuiltInFunction::Math_Floor: *inlineCandidateOpCode = Js::OpCode::InlineMathFloor; break; case Js::JavascriptBuiltInFunction::Math_Ceil: *inlineCandidateOpCode = Js::OpCode::InlineMathCeil; break; case Js::JavascriptBuiltInFunction::Math_Round: *inlineCandidateOpCode = Js::OpCode::InlineMathRound; break; case Js::JavascriptBuiltInFunction::Math_Min: *inlineCandidateOpCode = Js::OpCode::InlineMathMin; break; case Js::JavascriptBuiltInFunction::Math_Max: *inlineCandidateOpCode = Js::OpCode::InlineMathMax; break; case Js::JavascriptBuiltInFunction::Math_Imul: *inlineCandidateOpCode = Js::OpCode::InlineMathImul; break; case Js::JavascriptBuiltInFunction::Math_Clz32: *inlineCandidateOpCode = Js::OpCode::InlineMathClz; break; case Js::JavascriptBuiltInFunction::Math_Random: *inlineCandidateOpCode = Js::OpCode::InlineMathRandom; break; case Js::JavascriptBuiltInFunction::Math_Fround: *inlineCandidateOpCode = Js::OpCode::InlineMathFround; *returnType = ValueType::Float; break; case Js::JavascriptBuiltInFunction::JavascriptArray_Push: *inlineCandidateOpCode = Js::OpCode::InlineArrayPush; break; case Js::JavascriptBuiltInFunction::JavascriptArray_Pop: *inlineCandidateOpCode = Js::OpCode::InlineArrayPop; break; case Js::JavascriptBuiltInFunction::JavascriptArray_Concat: case Js::JavascriptBuiltInFunction::JavascriptArray_Reverse: case Js::JavascriptBuiltInFunction::JavascriptArray_Shift: case Js::JavascriptBuiltInFunction::JavascriptArray_Slice: case Js::JavascriptBuiltInFunction::JavascriptArray_Splice: case Js::JavascriptBuiltInFunction::JavascriptString_Link: case Js::JavascriptBuiltInFunction::JavascriptString_LocaleCompare: goto CallDirectCommon; case Js::JavascriptBuiltInFunction::JavascriptArray_Join: case Js::JavascriptBuiltInFunction::JavascriptString_CharAt: case Js::JavascriptBuiltInFunction::JavascriptString_Concat: case Js::JavascriptBuiltInFunction::JavascriptString_FromCharCode: case Js::JavascriptBuiltInFunction::JavascriptString_FromCodePoint: case Js::JavascriptBuiltInFunction::JavascriptString_Replace: case Js::JavascriptBuiltInFunction::JavascriptString_Slice: case Js::JavascriptBuiltInFunction::JavascriptString_Substr: case Js::JavascriptBuiltInFunction::JavascriptString_Substring: case Js::JavascriptBuiltInFunction::JavascriptString_ToLocaleLowerCase: case Js::JavascriptBuiltInFunction::JavascriptString_ToLocaleUpperCase: case Js::JavascriptBuiltInFunction::JavascriptString_ToLowerCase: case Js::JavascriptBuiltInFunction::JavascriptString_ToUpperCase: case Js::JavascriptBuiltInFunction::JavascriptString_Trim: case Js::JavascriptBuiltInFunction::JavascriptString_TrimLeft: case Js::JavascriptBuiltInFunction::JavascriptString_TrimRight: case Js::JavascriptBuiltInFunction::JavascriptString_PadStart: case Js::JavascriptBuiltInFunction::JavascriptString_PadEnd: *returnType = ValueType::String; goto CallDirectCommon; case Js::JavascriptBuiltInFunction::JavascriptArray_Includes: *returnType = ValueType::Boolean; goto CallDirectCommon; case Js::JavascriptBuiltInFunction::JavascriptArray_IndexOf: case Js::JavascriptBuiltInFunction::JavascriptArray_LastIndexOf: case Js::JavascriptBuiltInFunction::JavascriptArray_Unshift: case Js::JavascriptBuiltInFunction::JavascriptString_CharCodeAt: case Js::JavascriptBuiltInFunction::JavascriptString_IndexOf: case Js::JavascriptBuiltInFunction::JavascriptString_LastIndexOf: case Js::JavascriptBuiltInFunction::JavascriptString_Search: case Js::JavascriptBuiltInFunction::JavascriptRegExp_SymbolSearch: case Js::JavascriptBuiltInFunction::GlobalObject_ParseInt: *returnType = ValueType::GetNumberAndLikelyInt(true); goto CallDirectCommon; case Js::JavascriptBuiltInFunction::JavascriptString_Split: *returnType = ValueType::GetObject(ObjectType::Array).SetHasNoMissingValues(true).SetArrayTypeId(Js::TypeIds_Array); goto CallDirectCommon; case Js::JavascriptBuiltInFunction::JavascriptString_Match: case Js::JavascriptBuiltInFunction::JavascriptRegExp_Exec: *returnType = ValueType::GetObject(ObjectType::Array).SetHasNoMissingValues(true).SetArrayTypeId(Js::TypeIds_Array) .Merge(ValueType::Null); goto CallDirectCommon; CallDirectCommon: *inlineCandidateOpCode = Js::OpCode::CallDirect; break; case Js::JavascriptBuiltInFunction::JavascriptFunction_Apply: *inlineCandidateOpCode = Js::OpCode::InlineFunctionApply; break; case Js::JavascriptBuiltInFunction::JavascriptFunction_Call: *inlineCandidateOpCode = Js::OpCode::InlineFunctionCall; break; // The following are not currently inlined, but are tracked for their return type // TODO: Add more built-ins that return objects. May consider tracking all built-ins. case Js::JavascriptBuiltInFunction::JavascriptArray_NewInstance: *returnType = ValueType::GetObject(ObjectType::Array).SetHasNoMissingValues(true).SetArrayTypeId(Js::TypeIds_Array); break; case Js::JavascriptBuiltInFunction::Int8Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Int8MixedArray) : ValueType::GetObject(ObjectType::Int8Array); #else *returnType = ValueType::GetObject(ObjectType::Int8Array); #endif break; case Js::JavascriptBuiltInFunction::Uint8Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Uint8MixedArray) : ValueType::GetObject(ObjectType::Uint8Array); #else *returnType = ValueType::GetObject(ObjectType::Uint8Array); #endif break; case Js::JavascriptBuiltInFunction::Uint8ClampedArray_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Uint8ClampedMixedArray) : ValueType::GetObject(ObjectType::Uint8ClampedArray); #else *returnType = ValueType::GetObject(ObjectType::Uint8ClampedArray); #endif break; case Js::JavascriptBuiltInFunction::Int16Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Int16MixedArray) : ValueType::GetObject(ObjectType::Int16Array); #else *returnType = ValueType::GetObject(ObjectType::Int16Array); #endif break; case Js::JavascriptBuiltInFunction::Uint16Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Uint16MixedArray) : ValueType::GetObject(ObjectType::Uint16Array); #else *returnType = ValueType::GetObject(ObjectType::Uint16Array); #endif break; case Js::JavascriptBuiltInFunction::Int32Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Int32MixedArray) : ValueType::GetObject(ObjectType::Int32Array); #else *returnType = ValueType::GetObject(ObjectType::Int32Array); #endif break; case Js::JavascriptBuiltInFunction::Uint32Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Uint32MixedArray) : ValueType::GetObject(ObjectType::Uint32Array); #else *returnType = ValueType::GetObject(ObjectType::Uint32Array); #endif break; case Js::JavascriptBuiltInFunction::Float32Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Float32MixedArray) : ValueType::GetObject(ObjectType::Float32Array); #else *returnType = ValueType::GetObject(ObjectType::Float32Array); #endif break; case Js::JavascriptBuiltInFunction::Float64Array_NewInstance: #ifdef _M_X64 *returnType = (!PHASE_OFF1(Js::TypedArrayVirtualPhase)) ? ValueType::GetObject(ObjectType::Float64MixedArray) : ValueType::GetObject(ObjectType::Float64Array); #else *returnType = ValueType::GetObject(ObjectType::Float64Array); #endif break; case Js::JavascriptBuiltInFunction::Int64Array_NewInstance: *returnType = ValueType::GetObject(ObjectType::Int64Array); break; case Js::JavascriptBuiltInFunction::Uint64Array_NewInstance: *returnType = ValueType::GetObject(ObjectType::Uint64Array); break; case Js::JavascriptBuiltInFunction::BoolArray_NewInstance: *returnType = ValueType::GetObject(ObjectType::BoolArray); break; case Js::JavascriptBuiltInFunction::CharArray_NewInstance: *returnType = ValueType::GetObject(ObjectType::CharArray); break; #ifdef ENABLE_DOM_FAST_PATH case Js::JavascriptBuiltInFunction::DOMFastPathGetter: *inlineCandidateOpCode = Js::OpCode::DOMFastPathGetter; break; #endif #ifdef ENABLE_SIMDJS // SIMD_JS // we only inline, and hence type-spec on IA #if defined(_M_X64) || defined(_M_IX86) default: { #if 0 // TODO OOP JIT, inline SIMD // inline only if simdjs and simd128 type-spec is enabled. if (scriptContext->GetConfig()->IsSimdjsEnabled() && SIMD128_TYPE_SPEC_FLAG) { *inlineCandidateOpCode = scriptContext->GetThreadContext()->GetSimdOpcodeFromFuncInfo(funcInfo); } else #endif { return false; } } #endif #endif // ENABLE_SIMDJS } return true; }
// // Load persisted scope info. // void ScopeInfo::GetScopeInfo(Parser *parser, ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo, Scope* scope) { ScriptContext* scriptContext; ArenaAllocator* alloc; // Load scope attributes and push onto scope stack. scope->SetIsDynamic(this->isDynamic); if (this->isObject) { scope->SetIsObject(); } scope->SetMustInstantiate(this->mustInstantiate); if (!this->GetCanMergeWithBodyScope()) { scope->SetCannotMergeWithBodyScope(); } scope->SetHasOwnLocalInClosure(this->hasLocalInClosure); if (parser) { scriptContext = parser->GetScriptContext(); alloc = parser->GetAllocator(); } else { TRACE_BYTECODE(_u("\nRestore ScopeInfo: %s #symbols: %d %s\n"), funcInfo->name, symbolCount, isObject ? _u("isObject") : _u("")); Assert(!this->isCached || scope == funcInfo->GetBodyScope()); funcInfo->SetHasCachedScope(this->isCached); byteCodeGenerator->PushScope(scope); // The scope is already populated, so we're done. return; } // Load scope symbols // On first access to the scopeinfo, replace the ID's with PropertyRecord*'s to save the dictionary lookup // on later accesses. Replace them all before allocating Symbol's to prevent inconsistency on OOM. if (!this->areNamesCached && !PHASE_OFF1(Js::CacheScopeInfoNamesPhase)) { for (int i = 0; i < symbolCount; i++) { PropertyId propertyId = GetSymbolId(i); if (propertyId != 0) // There may be empty slots, e.g. "arguments" may have no slot { PropertyRecord const* name = scriptContext->GetPropertyName(propertyId); this->SetPropertyName(i, name); } } this->areNamesCached = true; } for (int i = 0; i < symbolCount; i++) { PropertyRecord const* name = nullptr; if (this->areNamesCached) { name = this->GetPropertyName(i); } else { PropertyId propertyId = GetSymbolId(i); if (propertyId != 0) // There may be empty slots, e.g. "arguments" may have no slot { name = scriptContext->GetPropertyName(propertyId); } } if (name != nullptr) { SymbolType symbolType = GetSymbolType(i); SymbolName symName(name->GetBuffer(), name->GetLength()); Symbol *sym = Anew(alloc, Symbol, symName, nullptr, symbolType); sym->SetScopeSlot(static_cast<PropertyId>(i)); sym->SetIsBlockVar(GetIsBlockVariable(i)); if (GetHasFuncAssignment(i)) { sym->RestoreHasFuncAssignment(); } scope->AddNewSymbol(sym); if (parser) { parser->RestorePidRefForSym(sym); } TRACE_BYTECODE(_u("%12s %d\n"), sym->GetName().GetBuffer(), sym->GetScopeSlot()); } } this->scope = scope; DebugOnly(scope->isRestored = true); }