Changeset 231889 in webkit


Ignore:
Timestamp:
May 16, 2018 10:21:41 PM (6 years ago)
Author:
sbarati@apple.com
Message:

UnlinkedFunctionExecutable doesn't need a parent source override field since it's only used for default class constructors
https://bugs.webkit.org/show_bug.cgi?id=185637

Reviewed by Keith Miller.

We had this general mechanism for overriding an UnlinkedFunctionExecutable's parent
source code. However, we were only using this for default class constructors. There
are only two types of default class constructors. This patch makes it so that
we just store this information inside of a single bit, and ask for the source
code as needed instead of holding it in a nullable field that is 24 bytes in size.

This brings UnlinkedFunctionExecutable's size down from 184 bytes to 160 bytes.
This has the consequence of making it allocated out of a 160 byte size class
instead of a 224 byte size class. This should bring down its memory footprint
by ~40%.

  • builtins/BuiltinExecutables.cpp:

(JSC::BuiltinExecutables::defaultConstructorSourceCode):
(JSC::BuiltinExecutables::createDefaultConstructor):
(JSC::BuiltinExecutables::createExecutable):

  • builtins/BuiltinExecutables.h:
  • bytecode/UnlinkedFunctionExecutable.cpp:

(JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
(JSC::UnlinkedFunctionExecutable::link):

  • bytecode/UnlinkedFunctionExecutable.h:
  • runtime/CodeCache.cpp:

(JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r231888 r231889  
     12018-05-16  Saam Barati  <sbarati@apple.com>
     2
     3        UnlinkedFunctionExecutable doesn't need a parent source override field since it's only used for default class constructors
     4        https://bugs.webkit.org/show_bug.cgi?id=185637
     5
     6        Reviewed by Keith Miller.
     7
     8        We had this general mechanism for overriding an UnlinkedFunctionExecutable's parent
     9        source code. However, we were only using this for default class constructors. There
     10        are only two types of default class constructors. This patch makes it so that
     11        we just store this information inside of a single bit, and ask for the source
     12        code as needed instead of holding it in a nullable field that is 24 bytes in size.
     13       
     14        This brings UnlinkedFunctionExecutable's size down from 184 bytes to 160 bytes.
     15        This has the consequence of making it allocated out of a 160 byte size class
     16        instead of a 224 byte size class. This should bring down its memory footprint
     17        by ~40%.
     18
     19        * builtins/BuiltinExecutables.cpp:
     20        (JSC::BuiltinExecutables::defaultConstructorSourceCode):
     21        (JSC::BuiltinExecutables::createDefaultConstructor):
     22        (JSC::BuiltinExecutables::createExecutable):
     23        * builtins/BuiltinExecutables.h:
     24        * bytecode/UnlinkedFunctionExecutable.cpp:
     25        (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable):
     26        (JSC::UnlinkedFunctionExecutable::link):
     27        * bytecode/UnlinkedFunctionExecutable.h:
     28        * runtime/CodeCache.cpp:
     29        (JSC::CodeCache::getUnlinkedGlobalFunctionExecutable):
     30
    1312018-05-16  Saam Barati  <sbarati@apple.com>
    232
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.cpp

    r230105 r231889  
    11/*
    2  * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343}
    4444
     45const SourceCode& BuiltinExecutables::defaultConstructorSourceCode(ConstructorKind constructorKind)
     46{
     47    switch (constructorKind) {
     48    case ConstructorKind::None:
     49        RELEASE_ASSERT_NOT_REACHED();
     50    case ConstructorKind::Base: {
     51        static NeverDestroyed<const String> baseConstructorCode(MAKE_STATIC_STRING_IMPL("(function () { })"));
     52        static LazyNeverDestroyed<SourceCode> result;
     53        static std::once_flag onceFlag;
     54        std::call_once(onceFlag, [&] {
     55            result.construct(makeSource(baseConstructorCode, { }));
     56        });
     57        return result;
     58    }
     59    case ConstructorKind::Extends: {
     60        static NeverDestroyed<const String> derivedConstructorCode(MAKE_STATIC_STRING_IMPL("(function (...args) { super(...args); })"));
     61        static LazyNeverDestroyed<SourceCode> result;
     62        static std::once_flag onceFlag;
     63        std::call_once(onceFlag, [&] {
     64            result.construct(makeSource(derivedConstructorCode, { }));
     65        });
     66        return result;
     67    }
     68    }
     69}
     70
    4571UnlinkedFunctionExecutable* BuiltinExecutables::createDefaultConstructor(ConstructorKind constructorKind, const Identifier& name)
    4672{
    47     static NeverDestroyed<const String> baseConstructorCode(MAKE_STATIC_STRING_IMPL("(function () { })"));
    48     static NeverDestroyed<const String> derivedConstructorCode(MAKE_STATIC_STRING_IMPL("(function (...args) { super(...args); })"));
    4973
    5074    switch (constructorKind) {
     
    5276        break;
    5377    case ConstructorKind::Base:
    54         return createExecutable(m_vm, makeSource(baseConstructorCode, { }), name, constructorKind, ConstructAbility::CanConstruct);
    5578    case ConstructorKind::Extends:
    56         return createExecutable(m_vm, makeSource(derivedConstructorCode, { }), name, constructorKind, ConstructAbility::CanConstruct);
     79        return createExecutable(m_vm, defaultConstructorSourceCode(constructorKind), name, constructorKind, ConstructAbility::CanConstruct);
    5780    }
    5881    ASSERT_NOT_REACHED();
     
    7497    JSTextPosition positionBeforeLastNewline;
    7598    ParserError error;
    76     bool isParsingDefaultConstructor = constructorKind != ConstructorKind::None;
    77     JSParserBuiltinMode builtinMode = isParsingDefaultConstructor ? JSParserBuiltinMode::NotBuiltin : JSParserBuiltinMode::Builtin;
    78     UnlinkedFunctionKind kind = isParsingDefaultConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction;
    79     SourceCode parentSourceOverride = isParsingDefaultConstructor ? source : SourceCode();
     99    bool isBuiltinDefaultClassConstructor = constructorKind != ConstructorKind::None;
     100    JSParserBuiltinMode builtinMode = isBuiltinDefaultClassConstructor ? JSParserBuiltinMode::NotBuiltin : JSParserBuiltinMode::Builtin;
     101    UnlinkedFunctionKind kind = isBuiltinDefaultClassConstructor ? UnlinkedNormalFunction : UnlinkedBuiltinFunction;
    80102    std::unique_ptr<ProgramNode> program = parse<ProgramNode>(
    81103        &vm, source, Identifier(), builtinMode,
     
    106128    metadata->overrideName(name);
    107129    VariableEnvironment dummyTDZVariables;
    108     UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, JSParserScriptMode::Classic, dummyTDZVariables, DerivedContextType::None, WTFMove(parentSourceOverride));
     130    UnlinkedFunctionExecutable* functionExecutable = UnlinkedFunctionExecutable::create(&vm, source, metadata, kind, constructAbility, JSParserScriptMode::Classic, dummyTDZVariables, DerivedContextType::None, isBuiltinDefaultClassConstructor);
    109131    return functionExecutable;
    110132}
  • trunk/Source/JavaScriptCore/builtins/BuiltinExecutables.h

    r230105 r231889  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5050#undef EXPOSE_BUILTIN_SOURCES
    5151
     52    static const SourceCode& defaultConstructorSourceCode(ConstructorKind);
    5253    UnlinkedFunctionExecutable* createDefaultConstructor(ConstructorKind, const Identifier& name);
    5354
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.cpp

    r231477 r231889  
    11/*
    2  * Copyright (C) 2012-2013, 2015-2016 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2012-2018 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727#include "UnlinkedFunctionExecutable.h"
    2828
     29#include "BuiltinExecutables.h"
    2930#include "BytecodeGenerator.h"
    3031#include "ClassInfo.h"
     
    4142namespace JSC {
    4243
    43 static_assert(sizeof(UnlinkedFunctionExecutable) <= 256, "UnlinkedFunctionExecutable should fit in a 256-byte cell.");
     44static_assert(sizeof(UnlinkedFunctionExecutable) <= 160, "UnlinkedFunctionExecutable should fit in a 160-byte cell. If you increase the size of this class, consider making a size class that perfectly fits it.");
    4445
    4546const ClassInfo UnlinkedFunctionExecutable::s_info = { "UnlinkedFunctionExecutable", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(UnlinkedFunctionExecutable) };
     
    7778}
    7879
    79 UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& parentSource, SourceCode&& parentSourceOverride, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType)
     80UnlinkedFunctionExecutable::UnlinkedFunctionExecutable(VM* vm, Structure* structure, const SourceCode& parentSource, FunctionMetadataNode* node, UnlinkedFunctionKind kind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, bool isBuiltinDefaultClassConstructor)
    8081    : Base(*vm, structure)
    8182    , m_firstLineOffset(node->firstLine() - parentSource.firstLine().oneBasedInt())
     
    9596    , m_hasCapturedVariables(false)
    9697    , m_isBuiltinFunction(kind == UnlinkedBuiltinFunction)
     98    , m_isBuiltinDefaultClassConstructor(isBuiltinDefaultClassConstructor)
    9799    , m_constructAbility(static_cast<unsigned>(constructAbility))
    98100    , m_constructorKind(static_cast<unsigned>(node->constructorKind()))
     
    104106    , m_ecmaName(node->ecmaName())
    105107    , m_inferredName(node->inferredName())
    106     , m_parentSourceOverride(WTFMove(parentSourceOverride))
    107108    , m_classSource(node->classSource())
    108109    , m_parentScopeTDZVariables(vm->m_compactVariableMap->get(parentScopeTDZVariables))
     
    115116    ASSERT(m_superBinding == static_cast<unsigned>(node->superBinding()));
    116117    ASSERT(m_derivedContextType == static_cast<unsigned>(derivedContextType));
     118    ASSERT(!(m_isBuiltinDefaultClassConstructor && constructorKind() == ConstructorKind::None));
    117119}
    118120
     
    133135FunctionExecutable* UnlinkedFunctionExecutable::link(VM& vm, const SourceCode& passedParentSource, std::optional<int> overrideLineNumber, Intrinsic intrinsic)
    134136{
    135     const SourceCode& parentSource = m_parentSourceOverride.isNull() ? passedParentSource : m_parentSourceOverride;
     137    const SourceCode& parentSource = !m_isBuiltinDefaultClassConstructor ? passedParentSource : BuiltinExecutables::defaultConstructorSourceCode(constructorKind());
    136138    unsigned firstLine = parentSource.firstLine().oneBasedInt() + m_firstLineOffset;
    137139    unsigned startOffset = parentSource.startOffset() + m_startOffset;
  • trunk/Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h

    r231477 r231889  
    11/*
    2  * Copyright (C) 2012-2016 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2012-2018 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5959    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
    6060
    61     static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, SourceCode&& parentSourceOverride = SourceCode())
     61    static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, JSParserScriptMode scriptMode, VariableEnvironment& parentScopeTDZVariables, DerivedContextType derivedContextType, bool isBuiltinDefaultClassConstructor = false)
    6262    {
    6363        UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap))
    64             UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTFMove(parentSourceOverride), node, unlinkedFunctionKind, constructAbility, scriptMode, parentScopeTDZVariables, derivedContextType);
     64            UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind, constructAbility, scriptMode, parentScopeTDZVariables, derivedContextType, isBuiltinDefaultClassConstructor);
    6565        instance->finishCreation(*vm);
    6666        return instance;
     
    140140
    141141private:
    142     UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, SourceCode&& parentSourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, VariableEnvironment&,  JSC::DerivedContextType);
     142    UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, JSParserScriptMode, VariableEnvironment&,  JSC::DerivedContextType, bool isBuiltinDefaultClassConstructor);
    143143
    144144    unsigned m_firstLineOffset;
     
    158158    unsigned m_hasCapturedVariables : 1;
    159159    unsigned m_isBuiltinFunction : 1;
     160    unsigned m_isBuiltinDefaultClassConstructor : 1;
    160161    unsigned m_constructAbility: 1;
    161162    unsigned m_constructorKind : 2;
     
    171172    Identifier m_ecmaName;
    172173    Identifier m_inferredName;
    173     SourceCode m_parentSourceOverride;
    174174    SourceCode m_classSource;
    175175
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r231018 r231889  
    151151    metadata->overrideName(name);
    152152    metadata->setEndPosition(positionBeforeLastNewline);
    153     // The Function constructor only has access to global variables, so no variables will be under TDZ.
     153    // The Function constructor only has access to global variables, so no variables will be under TDZ unless they're
     154    // in the global lexical environment, which we always TDZ check accesses from.
    154155    VariableEnvironment emptyTDZVariables;
    155156    ConstructAbility constructAbility = constructAbilityForParseMode(metadata->parseMode());
Note: See TracChangeset for help on using the changeset viewer.