Changeset 252684 in webkit for trunk/Source/JavaScriptCore/jit/JITOperations.cpp
- Timestamp:
- Nov 19, 2019, 9:53:38 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r252422 r252684 206 206 CodeBlock* codeBlock = callFrame->codeBlock(); 207 207 if (stubInfo->considerCaching(vm, codeBlock, baseValue.structureOrNull()) && !slot.isTaintedByOpaqueObject() && (slot.isCacheableValue() || slot.isCacheableGetter() || slot.isUnset())) 208 repatchGetBy ID(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByIDKind::Try);208 repatchGetBy(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByKind::Try); 209 209 210 210 return JSValue::encode(slot.getPureResult()); … … 262 262 CodeBlock* codeBlock = callFrame->codeBlock(); 263 263 if (stubInfo->considerCaching(vm, codeBlock, baseValue.structureOrNull())) 264 repatchGetBy ID(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByIDKind::Direct);264 repatchGetBy(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByKind::Direct); 265 265 266 266 RELEASE_AND_RETURN(scope, JSValue::encode(found ? slot.getValue(globalObject, ident) : jsUndefined())); … … 322 322 CodeBlock* codeBlock = callFrame->codeBlock(); 323 323 if (stubInfo->considerCaching(vm, codeBlock, baseValue.structureOrNull())) 324 repatchGetBy ID(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByIDKind::Normal);324 repatchGetBy(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByKind::Normal); 325 325 return found ? slot.getValue(globalObject, ident) : jsUndefined(); 326 326 })); … … 379 379 CodeBlock* codeBlock = callFrame->codeBlock(); 380 380 if (stubInfo->considerCaching(vm, codeBlock, baseValue.structureOrNull())) 381 repatchGetBy ID(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByIDKind::WithThis);381 repatchGetBy(globalObject, codeBlock, baseValue, ident, slot, *stubInfo, GetByKind::WithThis); 382 382 return found ? slot.getValue(globalObject, ident) : jsUndefined(); 383 383 })); … … 1920 1920 } 1921 1921 1922 static JSValue getByVal(JSGlobalObject* globalObject, CallFrame* callFrame, JSValue baseValue, JSValue subscript, ByValInfo* byValInfo, ReturnAddressPtr returnAddress)1922 ALWAYS_INLINE static JSValue getByVal(JSGlobalObject* globalObject, CallFrame* callFrame, ArrayProfile* arrayProfile, JSValue baseValue, JSValue subscript) 1923 1923 { 1924 1924 UNUSED_PARAM(callFrame); … … 1934 1934 if (JSValue result = baseValue.asCell()->fastGetOwnProperty(vm, structure, existingAtomString.get())) { 1935 1935 ASSERT(callFrame->bytecodeIndex() != BytecodeIndex(0)); 1936 if (byValInfo->stubInfo && byValInfo->cachedId.impl() != existingAtomString)1937 byValInfo->tookSlowPath = true;1938 1936 return result; 1939 1937 } … … 1943 1941 1944 1942 if (subscript.isInt32()) { 1945 ASSERT(callFrame->bytecodeIndex() != BytecodeIndex(0));1946 byValInfo->tookSlowPath = true;1947 1948 1943 int32_t i = subscript.asInt32(); 1949 1944 if (isJSString(baseValue)) { 1950 if (i >= 0 && asString(baseValue)->canGetIndex(i)) { 1951 ctiPatchCallByReturnAddress(returnAddress, operationGetByValString); 1945 if (i >= 0 && asString(baseValue)->canGetIndex(i)) 1952 1946 RELEASE_AND_RETURN(scope, asString(baseValue)->getIndex(globalObject, i)); 1953 }1954 byValInfo->arrayProfile->setOutOfBounds();1947 if (arrayProfile) 1948 arrayProfile->setOutOfBounds(); 1955 1949 } else if (baseValue.isObject()) { 1956 1950 JSObject* object = asObject(baseValue); … … 1971 1965 // out-of-bounds. 1972 1966 // https://bugs.webkit.org/show_bug.cgi?id=149886 1973 byValInfo->arrayProfile->setOutOfBounds(); 1967 if (arrayProfile) 1968 arrayProfile->setOutOfBounds(); 1974 1969 } 1975 1970 } … … 1985 1980 1986 1981 ASSERT(callFrame->bytecodeIndex() != BytecodeIndex(0)); 1987 if (byValInfo->stubInfo && (!isStringOrSymbol(subscript) || byValInfo->cachedId != property))1988 byValInfo->tookSlowPath = true;1989 1990 1982 RELEASE_AND_RETURN(scope, baseValue.get(globalObject, property)); 1991 1983 } 1992 1984 1993 static OptimizationResult tryGetByValOptimize(JSGlobalObject* globalObject, CallFrame* callFrame, JSValue baseValue, JSValue subscript, ByValInfo* byValInfo, ReturnAddressPtr returnAddress)1994 {1995 // See if it's worth optimizing this at all.1996 OptimizationResult optimizationResult = OptimizationResult::NotOptimized;1997 1998 VM& vm = globalObject->vm();1999 auto scope = DECLARE_THROW_SCOPE(vm);2000 2001 if (baseValue.isObject() && subscript.isInt32()) {2002 JSObject* object = asObject(baseValue);2003 2004 ASSERT(callFrame->bytecodeIndex() != BytecodeIndex(0));2005 ASSERT(!byValInfo->stubRoutine);2006 2007 if (hasOptimizableIndexing(object->structure(vm))) {2008 // Attempt to optimize.2009 Structure* structure = object->structure(vm);2010 JITArrayMode arrayMode = jitArrayModeForStructure(structure);2011 if (arrayMode != byValInfo->arrayMode) {2012 // If we reached this case, we got an interesting array mode we did not expect when we compiled.2013 // Let's update the profile to do better next time.2014 CodeBlock* codeBlock = callFrame->codeBlock();2015 ConcurrentJSLocker locker(codeBlock->m_lock);2016 byValInfo->arrayProfile->computeUpdatedPrediction(locker, codeBlock, structure);2017 2018 JIT::compileGetByVal(locker, vm, codeBlock, byValInfo, returnAddress, arrayMode);2019 optimizationResult = OptimizationResult::Optimized;2020 }2021 }2022 2023 // If we failed to patch and we have some object that intercepts indexed get, then don't even wait until 10 times.2024 if (optimizationResult != OptimizationResult::Optimized && object->structure(vm)->typeInfo().interceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero())2025 optimizationResult = OptimizationResult::GiveUp;2026 }2027 2028 if (baseValue.isObject() && isStringOrSymbol(subscript)) {2029 const Identifier propertyName = subscript.toPropertyKey(globalObject);2030 RETURN_IF_EXCEPTION(scope, OptimizationResult::GiveUp);2031 if (subscript.isSymbol() || !parseIndex(propertyName)) {2032 ASSERT(callFrame->bytecodeIndex() != BytecodeIndex(0));2033 ASSERT(!byValInfo->stubRoutine);2034 if (byValInfo->seen) {2035 if (byValInfo->cachedId == propertyName) {2036 JIT::compileGetByValWithCachedId(vm, callFrame->codeBlock(), byValInfo, returnAddress, propertyName);2037 optimizationResult = OptimizationResult::Optimized;2038 } else {2039 // Seem like a generic property access site.2040 optimizationResult = OptimizationResult::GiveUp;2041 }2042 } else {2043 CodeBlock* codeBlock = callFrame->codeBlock();2044 ConcurrentJSLocker locker(codeBlock->m_lock);2045 byValInfo->seen = true;2046 byValInfo->cachedId = propertyName;2047 if (subscript.isSymbol())2048 byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript));2049 optimizationResult = OptimizationResult::SeenOnce;2050 }2051 }2052 }2053 2054 if (optimizationResult != OptimizationResult::Optimized && optimizationResult != OptimizationResult::SeenOnce) {2055 // If we take slow path more than 10 times without patching then make sure we2056 // never make that mistake again. For cases where we see non-index-intercepting2057 // objects, this gives 10 iterations worth of opportunity for us to observe2058 // that the get_by_val may be polymorphic. We count up slowPathCount even if2059 // the result is GiveUp.2060 if (++byValInfo->slowPathCount >= 10)2061 optimizationResult = OptimizationResult::GiveUp;2062 }2063 2064 return optimizationResult;2065 }2066 2067 1985 extern "C" { 2068 1986 2069 EncodedJSValue JIT_OPERATION operationGetByValGeneric(JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)1987 EncodedJSValue JIT_OPERATION operationGetByValGeneric(JSGlobalObject* globalObject, StructureStubInfo* stubInfo, ArrayProfile* profile, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) 2070 1988 { 2071 1989 VM& vm = globalObject->vm(); … … 2075 1993 JSValue subscript = JSValue::decode(encodedSubscript); 2076 1994 2077 JSValue result = getByVal(globalObject, callFrame, baseValue, subscript, byValInfo, ReturnAddressPtr(OUR_RETURN_ADDRESS)); 2078 return JSValue::encode(result); 2079 } 2080 2081 EncodedJSValue JIT_OPERATION operationGetByValOptimize(JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo) 1995 stubInfo->tookSlowPath = true; 1996 1997 return JSValue::encode(getByVal(globalObject, callFrame, profile, baseValue, subscript)); 1998 } 1999 2000 EncodedJSValue JIT_OPERATION operationGetByValOptimize(JSGlobalObject* globalObject, StructureStubInfo* stubInfo, ArrayProfile* profile, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript) 2082 2001 { 2083 2002 VM& vm = globalObject->vm(); … … 2088 2007 JSValue baseValue = JSValue::decode(encodedBase); 2089 2008 JSValue subscript = JSValue::decode(encodedSubscript); 2090 ReturnAddressPtr returnAddress = ReturnAddressPtr(OUR_RETURN_ADDRESS); 2091 OptimizationResult result = tryGetByValOptimize(globalObject, callFrame, baseValue, subscript, byValInfo, returnAddress); 2092 RETURN_IF_EXCEPTION(scope, { }); 2093 if (result == OptimizationResult::GiveUp) { 2094 // Don't ever try to optimize. 2095 byValInfo->tookSlowPath = true; 2096 ctiPatchCallByReturnAddress(returnAddress, operationGetByValGeneric); 2097 } 2098 2099 RELEASE_AND_RETURN(scope, JSValue::encode(getByVal(globalObject, callFrame, baseValue, subscript, byValInfo, returnAddress))); 2009 2010 if (baseValue.isCell() && subscript.isInt32()) { 2011 if (stubInfo->considerCaching(vm, callFrame->codeBlock(), baseValue.structureOrNull())) 2012 repatchArrayGetByVal(globalObject, callFrame->codeBlock(), baseValue, subscript, *stubInfo); 2013 } 2014 2015 if (baseValue.isCell() && isStringOrSymbol(subscript)) { 2016 const Identifier propertyName = subscript.toPropertyKey(globalObject); 2017 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 2018 if (subscript.isSymbol() || !parseIndex(propertyName)) { 2019 scope.release(); 2020 return JSValue::encode(baseValue.getPropertySlot(globalObject, propertyName, [&] (bool found, PropertySlot& slot) -> JSValue { 2021 LOG_IC((ICEvent::OperationGetByValOptimize, baseValue.classInfoOrNull(vm), propertyName, baseValue == slot.slotBase())); 2022 2023 CodeBlock* codeBlock = callFrame->codeBlock(); 2024 if (stubInfo->considerCaching(vm, codeBlock, baseValue.structureOrNull())) 2025 repatchGetBy(globalObject, codeBlock, baseValue, propertyName, slot, *stubInfo, GetByKind::NormalByVal); 2026 return found ? slot.getValue(globalObject, propertyName) : jsUndefined(); 2027 })); 2028 } 2029 } 2030 2031 RELEASE_AND_RETURN(scope, JSValue::encode(getByVal(globalObject, callFrame, profile, baseValue, subscript))); 2100 2032 } 2101 2033 … … 2169 2101 } 2170 2102 2171 EncodedJSValue JIT_OPERATION operationGetByValString(JSGlobalObject* globalObject, EncodedJSValue encodedBase, EncodedJSValue encodedSubscript, ByValInfo* byValInfo)2172 {2173 VM& vm = globalObject->vm();2174 CallFrame* callFrame = DECLARE_CALL_FRAME(vm);2175 JITOperationPrologueCallFrameTracer tracer(vm, callFrame);2176 auto scope = DECLARE_THROW_SCOPE(vm);2177 JSValue baseValue = JSValue::decode(encodedBase);2178 JSValue subscript = JSValue::decode(encodedSubscript);2179 2180 JSValue result;2181 if (LIKELY(subscript.isUInt32())) {2182 uint32_t i = subscript.asUInt32();2183 if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))2184 RELEASE_AND_RETURN(scope, JSValue::encode(asString(baseValue)->getIndex(globalObject, i)));2185 2186 result = baseValue.get(globalObject, i);2187 RETURN_IF_EXCEPTION(scope, encodedJSValue());2188 if (!isJSString(baseValue)) {2189 ASSERT(callFrame->bytecodeIndex() != BytecodeIndex(0));2190 auto getByValFunction = byValInfo->stubRoutine ? operationGetByValGeneric : operationGetByValOptimize;2191 ctiPatchCallByReturnAddress(ReturnAddressPtr(OUR_RETURN_ADDRESS), getByValFunction);2192 }2193 } else {2194 baseValue.requireObjectCoercible(globalObject);2195 RETURN_IF_EXCEPTION(scope, encodedJSValue());2196 auto property = subscript.toPropertyKey(globalObject);2197 RETURN_IF_EXCEPTION(scope, encodedJSValue());2198 scope.release();2199 result = baseValue.get(globalObject, property);2200 }2201 2202 return JSValue::encode(result);2203 }2204 2205 2103 static bool deleteById(JSGlobalObject* globalObject, CallFrame* callFrame, VM& vm, JSValue base, UniquedStringImpl* uid) 2206 2104 {
Note:
See TracChangeset
for help on using the changeset viewer.