2017-08-12 16:48:01 +00:00
/*
2022-10-23 02:55:20 +00:00
* Copyright ( C ) 2013 - 2019 Apple Inc . All rights reserved .
2017-08-12 16:48:01 +00:00
*
* 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 .
*/
# include "config.h"
# include "DFGDesiredWatchpoints.h"
# if ENABLE(DFG_JIT)
# include "CodeBlock.h"
2022-10-23 02:55:20 +00:00
# include "DFGGraph.h"
2017-08-12 16:48:01 +00:00
# include "JSCInlines.h"
namespace JSC { namespace DFG {
void ArrayBufferViewWatchpointAdaptor : : add (
CodeBlock * codeBlock , JSArrayBufferView * view , CommonData & common )
{
2022-10-23 02:55:20 +00:00
// view is already frozen. If it is deallocated, jettisoning happens.
CodeBlockJettisoningWatchpoint * watchpoint = nullptr ;
{
ConcurrentJSLocker locker ( codeBlock - > m_lock ) ;
watchpoint = common . watchpoints . add ( codeBlock ) ;
}
ArrayBuffer * arrayBuffer = view - > possiblySharedBuffer ( ) ;
if ( ! arrayBuffer ) {
watchpoint - > fire ( codeBlock - > vm ( ) , StringFireDetail ( " ArrayBuffer could not be allocated, probably because of OOM. " ) ) ;
return ;
}
2017-08-12 16:48:01 +00:00
// FIXME: We don't need to set this watchpoint at all for shared buffers.
// https://bugs.webkit.org/show_bug.cgi?id=164108
2022-10-23 02:55:20 +00:00
arrayBuffer - > detachingWatchpointSet ( ) . add ( WTFMove ( watchpoint ) ) ;
2017-08-12 16:48:01 +00:00
}
2020-08-29 13:27:11 +00:00
void SymbolTableAdaptor : : add (
CodeBlock * codeBlock , SymbolTable * symbolTable , CommonData & common )
2017-08-12 16:48:01 +00:00
{
2022-10-23 02:55:20 +00:00
codeBlock - > addConstant ( ConcurrentJSLocker ( codeBlock - > m_lock ) , symbolTable ) ; // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
CodeBlockJettisoningWatchpoint * watchpoint = nullptr ;
{
ConcurrentJSLocker locker ( codeBlock - > m_lock ) ;
watchpoint = common . watchpoints . add ( codeBlock ) ;
}
symbolTable - > singleton ( ) . add ( WTFMove ( watchpoint ) ) ;
2020-08-29 13:27:11 +00:00
}
void FunctionExecutableAdaptor : : add (
CodeBlock * codeBlock , FunctionExecutable * executable , CommonData & common )
{
2022-10-23 02:55:20 +00:00
codeBlock - > addConstant ( ConcurrentJSLocker ( codeBlock - > m_lock ) , executable ) ; // For common users, it doesn't really matter if it's weak or not. If references to it go away, we go away, too.
CodeBlockJettisoningWatchpoint * watchpoint = nullptr ;
{
ConcurrentJSLocker locker ( codeBlock - > m_lock ) ;
watchpoint = common . watchpoints . add ( codeBlock ) ;
}
executable - > singleton ( ) . add ( WTFMove ( watchpoint ) ) ;
2017-08-12 16:48:01 +00:00
}
void AdaptiveStructureWatchpointAdaptor : : add (
CodeBlock * codeBlock , const ObjectPropertyCondition & key , CommonData & common )
{
2022-10-23 02:55:20 +00:00
VM & vm = codeBlock - > vm ( ) ;
2017-08-12 16:48:01 +00:00
switch ( key . kind ( ) ) {
2022-10-23 02:55:20 +00:00
case PropertyCondition : : Equivalence : {
AdaptiveInferredPropertyValueWatchpoint * watchpoint = nullptr ;
{
ConcurrentJSLocker locker ( codeBlock - > m_lock ) ;
watchpoint = common . adaptiveInferredPropertyValueWatchpoints . add ( key , codeBlock ) ;
}
watchpoint - > install ( vm ) ;
2017-08-12 16:48:01 +00:00
break ;
2022-10-23 02:55:20 +00:00
}
default : {
AdaptiveStructureWatchpoint * watchpoint = nullptr ;
{
ConcurrentJSLocker locker ( codeBlock - > m_lock ) ;
watchpoint = common . adaptiveStructureWatchpoints . add ( key , codeBlock ) ;
}
watchpoint - > install ( vm ) ;
2017-08-12 16:48:01 +00:00
break ;
}
2022-10-23 02:55:20 +00:00
}
2017-08-12 16:48:01 +00:00
}
DesiredWatchpoints : : DesiredWatchpoints ( ) { }
DesiredWatchpoints : : ~ DesiredWatchpoints ( ) { }
void DesiredWatchpoints : : addLazily ( WatchpointSet * set )
{
m_sets . addLazily ( set ) ;
}
void DesiredWatchpoints : : addLazily ( InlineWatchpointSet & set )
{
m_inlineSets . addLazily ( & set ) ;
}
2020-08-29 13:27:11 +00:00
void DesiredWatchpoints : : addLazily ( SymbolTable * symbolTable )
2017-08-12 16:48:01 +00:00
{
2020-08-29 13:27:11 +00:00
m_symbolTables . addLazily ( symbolTable ) ;
}
void DesiredWatchpoints : : addLazily ( FunctionExecutable * executable )
{
m_functionExecutables . addLazily ( executable ) ;
2017-08-12 16:48:01 +00:00
}
void DesiredWatchpoints : : addLazily ( JSArrayBufferView * view )
{
m_bufferViews . addLazily ( view ) ;
}
void DesiredWatchpoints : : addLazily ( const ObjectPropertyCondition & key )
{
m_adaptiveStructureSets . addLazily ( key ) ;
}
bool DesiredWatchpoints : : consider ( Structure * structure )
{
if ( ! structure - > dfgShouldWatch ( ) )
return false ;
addLazily ( structure - > transitionWatchpointSet ( ) ) ;
return true ;
}
void DesiredWatchpoints : : reallyAdd ( CodeBlock * codeBlock , CommonData & commonData )
{
m_sets . reallyAdd ( codeBlock , commonData ) ;
m_inlineSets . reallyAdd ( codeBlock , commonData ) ;
2020-08-29 13:27:11 +00:00
m_symbolTables . reallyAdd ( codeBlock , commonData ) ;
m_functionExecutables . reallyAdd ( codeBlock , commonData ) ;
2017-08-12 16:48:01 +00:00
m_bufferViews . reallyAdd ( codeBlock , commonData ) ;
m_adaptiveStructureSets . reallyAdd ( codeBlock , commonData ) ;
}
bool DesiredWatchpoints : : areStillValid ( ) const
{
return m_sets . areStillValid ( )
& & m_inlineSets . areStillValid ( )
2020-08-29 13:27:11 +00:00
& & m_symbolTables . areStillValid ( )
& & m_functionExecutables . areStillValid ( )
2017-08-12 16:48:01 +00:00
& & m_bufferViews . areStillValid ( )
2020-08-29 13:27:11 +00:00
& & m_adaptiveStructureSets . areStillValid ( ) ;
2017-08-12 16:48:01 +00:00
}
void DesiredWatchpoints : : dumpInContext ( PrintStream & out , DumpContext * context ) const
{
2022-10-23 02:55:20 +00:00
Prefix noPrefix ( Prefix : : NoHeader ) ;
Prefix & prefix = context & & context - > graph ? context - > graph - > prefix ( ) : noPrefix ;
out . print ( prefix , " Desired watchpoints: \n " ) ;
out . print ( prefix , " Watchpoint sets: " , inContext ( m_sets , context ) , " \n " ) ;
out . print ( prefix , " Inline watchpoint sets: " , inContext ( m_inlineSets , context ) , " \n " ) ;
out . print ( prefix , " SymbolTables: " , inContext ( m_symbolTables , context ) , " \n " ) ;
out . print ( prefix , " FunctionExecutables: " , inContext ( m_functionExecutables , context ) , " \n " ) ;
out . print ( prefix , " Buffer views: " , inContext ( m_bufferViews , context ) , " \n " ) ;
out . print ( prefix , " Object property conditions: " , inContext ( m_adaptiveStructureSets , context ) , " \n " ) ;
2017-08-12 16:48:01 +00:00
}
} } // namespace JSC::DFG
# endif // ENABLE(DFG_JIT)