Changeset 212618 in webkit


Ignore:
Timestamp:
Feb 19, 2017 5:46:04 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

CachedCall should let GC know to keep its arguments alive.
https://bugs.webkit.org/show_bug.cgi?id=168567
<rdar://problem/30475767>

Reviewed by Saam Barati.

Source/JavaScriptCore:

We fix this by having CachedCall use a MarkedArgumentBuffer to store its
arguments instead of a Vector.

Also declared CachedCall, MarkedArgumentBuffer, and ProtoCallFrame as
WTF_FORBID_HEAP_ALLOCATION because they rely on being stack allocated for
correctness.

  • interpreter/CachedCall.h:

(JSC::CachedCall::CachedCall):
(JSC::CachedCall::call):
(JSC::CachedCall::clearArguments):
(JSC::CachedCall::appendArgument):
(JSC::CachedCall::setArgument): Deleted.

  • interpreter/CallFrame.h:

(JSC::ExecState::emptyList):

  • interpreter/Interpreter.cpp:

(JSC::Interpreter::prepareForRepeatCall):

  • interpreter/Interpreter.h:
  • interpreter/ProtoCallFrame.h:
  • runtime/ArgList.cpp:

(JSC::MarkedArgumentBuffer::expandCapacity):

  • runtime/ArgList.h:

(JSC::MarkedArgumentBuffer::ensureCapacity):

  • runtime/StringPrototype.cpp:

(JSC::replaceUsingRegExpSearch):

  • runtime/VM.cpp:

(JSC::VM::VM):

  • runtime/VM.h:

Source/WTF:

Added a WTF_FORBID_HEAP_ALLOCATION that will cause a compilation failure if
a class declared with it is malloced.

While this doesn't prevent that class declared WTF_FORBID_HEAP_ALLOCATION from
being embedded in another class that is heap allocated, it does at minimum
document the intent and gives the users of this class a chance to do the
right thing.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/ForbidHeapAllocation.h: Added.
Location:
trunk/Source
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r212616 r212618  
     12017-02-19  Mark Lam  <mark.lam@apple.com>
     2
     3        CachedCall should let GC know to keep its arguments alive.
     4        https://bugs.webkit.org/show_bug.cgi?id=168567
     5        <rdar://problem/30475767>
     6
     7        Reviewed by Saam Barati.
     8
     9        We fix this by having CachedCall use a MarkedArgumentBuffer to store its
     10        arguments instead of a Vector.
     11
     12        Also declared CachedCall, MarkedArgumentBuffer, and ProtoCallFrame as
     13        WTF_FORBID_HEAP_ALLOCATION because they rely on being stack allocated for
     14        correctness.
     15
     16        * interpreter/CachedCall.h:
     17        (JSC::CachedCall::CachedCall):
     18        (JSC::CachedCall::call):
     19        (JSC::CachedCall::clearArguments):
     20        (JSC::CachedCall::appendArgument):
     21        (JSC::CachedCall::setArgument): Deleted.
     22        * interpreter/CallFrame.h:
     23        (JSC::ExecState::emptyList):
     24        * interpreter/Interpreter.cpp:
     25        (JSC::Interpreter::prepareForRepeatCall):
     26        * interpreter/Interpreter.h:
     27        * interpreter/ProtoCallFrame.h:
     28        * runtime/ArgList.cpp:
     29        (JSC::MarkedArgumentBuffer::expandCapacity):
     30        * runtime/ArgList.h:
     31        (JSC::MarkedArgumentBuffer::ensureCapacity):
     32        * runtime/StringPrototype.cpp:
     33        (JSC::replaceUsingRegExpSearch):
     34        * runtime/VM.cpp:
     35        (JSC::VM::VM):
     36        * runtime/VM.h:
     37
    1382017-02-19  Commit Queue  <commit-queue@webkit.org>
    239
  • trunk/Source/JavaScriptCore/interpreter/CachedCall.h

    r206525 r212618  
    11/*
    2  * Copyright (C) 2009, 2013, 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3434#include "VMEntryScope.h"
    3535#include "VMInlines.h"
     36#include <wtf/ForbidHeapAllocation.h>
    3637
    3738namespace JSC {
    3839    class CachedCall {
    39         WTF_MAKE_NONCOPYABLE(CachedCall); WTF_MAKE_FAST_ALLOCATED;
     40        WTF_MAKE_NONCOPYABLE(CachedCall);
     41        WTF_FORBID_HEAP_ALLOCATION;
    4042    public:
    4143        CachedCall(CallFrame* callFrame, JSFunction* function, int argumentCount)
     
    5052            ASSERT(!function->isHostFunctionNonInline());
    5153            if (UNLIKELY(vm.isSafeToRecurseSoft())) {
    52                 m_arguments.resize(argumentCount);
    53                 m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, &m_protoCallFrame, function, argumentCount + 1, function->scope(), m_arguments.data());
     54                m_arguments.ensureCapacity(argumentCount);
     55                m_closure = m_interpreter->prepareForRepeatCall(function->jsExecutable(), callFrame, &m_protoCallFrame, function, argumentCount + 1, function->scope(), m_arguments);
    5456            } else
    5557                throwStackOverflowError(callFrame, scope);
     
    6062        {
    6163            ASSERT(m_valid);
     64            ASSERT(m_arguments.size() == static_cast<size_t>(m_protoCallFrame.argumentCount()));
    6265            return m_interpreter->execute(m_closure);
    6366        }
    6467        void setThis(JSValue v) { m_protoCallFrame.setThisValue(v); }
    65         void setArgument(int n, JSValue v) { m_protoCallFrame.setArgument(n, v); }
     68
     69        void clearArguments() { m_arguments.clear(); }
     70        void appendArgument(JSValue v) { m_arguments.append(v); }
    6671
    6772    private:
     
    7176        VMEntryScope m_entryScope;
    7277        ProtoCallFrame m_protoCallFrame;
    73         Vector<JSValue> m_arguments;
     78        MarkedArgumentBuffer m_arguments;
    7479        CallFrameClosure m_closure;
    7580    };
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r212483 r212618  
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2007-2008, 2011, 2013-2016 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    120120        AtomicStringTable* atomicStringTable() const { return vm().atomicStringTable(); }
    121121        const CommonIdentifiers& propertyNames() const { return *vm().propertyNames; }
    122         const MarkedArgumentBuffer& emptyList() const { return *vm().emptyList; }
     122        const ArgList& emptyList() const { return *vm().emptyList; }
    123123        Interpreter* interpreter() { return vm().interpreter; }
    124124        Heap* heap() { return &vm().heap; }
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r211642 r212618  
    11/*
    2  * Copyright (C) 2008-2010, 2012-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
    44 *
     
    10061006}
    10071007
    1008 CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, JSValue* args)
     1008CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* functionExecutable, CallFrame* callFrame, ProtoCallFrame* protoCallFrame, JSFunction* function, int argumentCountIncludingThis, JSScope* scope, const ArgList& args)
    10091009{
    10101010    VM& vm = *scope->vm();
     
    10261026    size_t argsCount = argumentCountIncludingThis;
    10271027
    1028     protoCallFrame->init(newCodeBlock, function, jsUndefined(), argsCount, args);
     1028    protoCallFrame->init(newCodeBlock, function, jsUndefined(), argsCount, args.data());
    10291029    // Return the successful closure:
    10301030    CallFrameClosure result = { callFrame, protoCallFrame, function, functionExecutable, &vm, scope, newCodeBlock->numParameters(), argumentCountIncludingThis };
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.h

    r211642 r212618  
    11/*
    2  * Copyright (C) 2008, 2013, 2015-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
    33 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
    44 *
     
    155155        enum ExecutionFlag { Normal, InitializeAndReturn };
    156156
    157         CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, JSValue*);
     157        CallFrameClosure prepareForRepeatCall(FunctionExecutable*, CallFrame*, ProtoCallFrame*, JSFunction*, int argumentCountIncludingThis, JSScope*, const ArgList&);
    158158
    159159        JSValue execute(CallFrameClosure&);
  • trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.h

    r206525 r212618  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2013-2017 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2727
    2828#include "Register.h"
     29#include <wtf/ForbidHeapAllocation.h>
    2930
    3031namespace JSC {
    3132
    3233struct JS_EXPORT_PRIVATE ProtoCallFrame {
     34    WTF_FORBID_HEAP_ALLOCATION;
     35public:
    3336    Register codeBlockValue;
    3437    Register calleeValue;
  • trunk/Source/JavaScriptCore/runtime/ArgList.cpp

    r209897 r212618  
    11/*
    2  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2016 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
    33 *
    44 *  This library is free software; you can redistribute it and/or
     
    6464}
    6565
     66void MarkedArgumentBuffer::slowEnsureCapacity(size_t requestedCapacity)
     67{
     68    int newCapacity = Checked<int>(requestedCapacity).unsafeGet();
     69    expandCapacity(newCapacity);
     70}
     71
    6672void MarkedArgumentBuffer::expandCapacity()
    6773{
    6874    int newCapacity = (Checked<int>(m_capacity) * 2).unsafeGet();
     75    expandCapacity(newCapacity);
     76}
     77
     78void MarkedArgumentBuffer::expandCapacity(int newCapacity)
     79{
     80    ASSERT(m_capacity < newCapacity);
    6981    size_t size = (Checked<size_t>(newCapacity) * sizeof(EncodedJSValue)).unsafeGet();
    7082    EncodedJSValue* newBuffer = static_cast<EncodedJSValue*>(fastMalloc(size));
  • trunk/Source/JavaScriptCore/runtime/ArgList.h

    r209897 r212618  
    11/*
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007, 2008, 2009, 2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    2323
    2424#include "CallFrame.h"
     25#include <wtf/ForbidHeapAllocation.h>
    2526#include <wtf/HashSet.h>
    2627
     
    2930class MarkedArgumentBuffer {
    3031    WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
     32    WTF_FORBID_HEAP_ALLOCATION;
    3133    friend class VM;
    3234    friend class ArgList;
     
    9597    static void markLists(SlotVisitor&, ListSet&);
    9698
     99    void ensureCapacity(size_t requestedCapacity)
     100    {
     101        if (requestedCapacity > static_cast<size_t>(m_capacity))
     102            slowEnsureCapacity(requestedCapacity);
     103    }
     104
    97105private:
    98106    void expandCapacity();
     107    void expandCapacity(int newCapacity);
     108    void slowEnsureCapacity(size_t requestedCapacity);
    99109
    100110    void addMarkSet(JSValue);
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r211247 r212618  
    11/*
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2004-2008, 2013, 2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2004-2017 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2009 Torch Mobile, Inc.
    55 *  Copyright (C) 2015 Jordan Harband (ljharb@gmail.com)
     
    540540
    541541                unsigned i = 0;
     542                cachedCall.clearArguments();
    542543                for (; i < regExp->numSubpatterns() + 1; ++i) {
    543544                    int matchStart = ovector[i * 2];
     
    545546
    546547                    if (matchStart < 0)
    547                         cachedCall.setArgument(i, jsUndefined());
     548                        cachedCall.appendArgument(jsUndefined());
    548549                    else
    549                         cachedCall.setArgument(i, jsSubstring(&vm, source, matchStart, matchLen));
     550                        cachedCall.appendArgument(jsSubstring(&vm, source, matchStart, matchLen));
    550551                }
    551552
    552                 cachedCall.setArgument(i++, jsNumber(result.start));
    553                 cachedCall.setArgument(i++, string);
     553                cachedCall.appendArgument(jsNumber(result.start));
     554                cachedCall.appendArgument(string);
    554555
    555556                cachedCall.setThis(jsUndefined());
     
    579580
    580581                unsigned i = 0;
     582                cachedCall.clearArguments();
    581583                for (; i < regExp->numSubpatterns() + 1; ++i) {
    582584                    int matchStart = ovector[i * 2];
     
    584586
    585587                    if (matchStart < 0)
    586                         cachedCall.setArgument(i, jsUndefined());
     588                        cachedCall.appendArgument(jsUndefined());
    587589                    else
    588                         cachedCall.setArgument(i, jsSubstring(&vm, source, matchStart, matchLen));
     590                        cachedCall.appendArgument(jsSubstring(&vm, source, matchStart, matchLen));
    589591                }
    590592
    591                 cachedCall.setArgument(i++, jsNumber(result.start));
    592                 cachedCall.setArgument(i++, string);
     593                cachedCall.appendArgument(jsNumber(result.start));
     594                cachedCall.appendArgument(string);
    593595
    594596                cachedCall.setThis(jsUndefined());
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r212365 r212618  
    181181    , m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable)
    182182    , propertyNames(nullptr)
    183     , emptyList(new MarkedArgumentBuffer)
     183    , emptyList(new ArgList)
    184184    , machineCodeBytesPerBytecodeWordForBaselineJIT(std::make_unique<SimpleStats>())
    185185    , customGetterSetterFunctionMap(*this)
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r212365 r212618  
    386386    TemplateRegistryKeyTable m_templateRegistryKeytable;
    387387    CommonIdentifiers* propertyNames;
    388     const MarkedArgumentBuffer* emptyList; // Lists are supposed to be allocated on the stack to have their elements properly marked, which is not the case here - but this list has nothing to mark.
     388    const ArgList* emptyList;
    389389    SmallStrings smallStrings;
    390390    NumericStrings numericStrings;
  • trunk/Source/WTF/ChangeLog

    r212616 r212618  
     12017-02-19  Mark Lam  <mark.lam@apple.com>
     2
     3        CachedCall should let GC know to keep its arguments alive.
     4        https://bugs.webkit.org/show_bug.cgi?id=168567
     5        <rdar://problem/30475767>
     6
     7        Reviewed by Saam Barati.
     8
     9        Added a WTF_FORBID_HEAP_ALLOCATION that will cause a compilation failure if
     10        a class declared with it is malloced.
     11
     12        While this doesn't prevent that class declared WTF_FORBID_HEAP_ALLOCATION from
     13        being embedded in another class that is heap allocated, it does at minimum
     14        document the intent and gives the users of this class a chance to do the
     15        right thing.
     16
     17        * WTF.xcodeproj/project.pbxproj:
     18        * wtf/ForbidHeapAllocation.h: Added.
     19
    1202017-02-19  Commit Queue  <commit-queue@webkit.org>
    221
  • trunk/Source/WTF/WTF.xcodeproj/project.pbxproj

    r212180 r212618  
    369369                EB95E1F0161A72410089A2F5 /* ByteOrder.h in Headers */ = {isa = PBXBuildFile; fileRef = EB95E1EF161A72410089A2F5 /* ByteOrder.h */; };
    370370                FE8225311B2A1E5B00BA68FD /* NakedPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = FE8225301B2A1E5B00BA68FD /* NakedPtr.h */; };
     371                FE86A8751E59440200111BBF /* ForbidHeapAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = FE86A8741E59440200111BBF /* ForbidHeapAllocation.h */; };
    371372                FE8925B01D00DAEC0046907E /* Indenter.h in Headers */ = {isa = PBXBuildFile; fileRef = FE8925AF1D00DAEC0046907E /* Indenter.h */; };
    372373                FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; };
     
    752753                F72BBDB107FA424886178B9E /* SymbolImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolImpl.cpp; sourceTree = "<group>"; };
    753754                FE8225301B2A1E5B00BA68FD /* NakedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NakedPtr.h; sourceTree = "<group>"; };
     755                FE86A8741E59440200111BBF /* ForbidHeapAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ForbidHeapAllocation.h; sourceTree = "<group>"; };
    754756                FE8925AF1D00DAEC0046907E /* Indenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Indenter.h; sourceTree = "<group>"; };
    755757                FEDACD3B1630F83F00C69634 /* StackStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackStats.cpp; sourceTree = "<group>"; };
     
    963965                                0F9D335C165DBA73005AD387 /* FilePrintStream.h */,
    964966                                0F2B66A517B6B4F700A7AE3F /* FlipBytes.h */,
     967                                FE86A8741E59440200111BBF /* ForbidHeapAllocation.h */,
    965968                                A8A472A6151A825A004123FF /* Forward.h */,
    966969                                83F2BADE1CF9524E003E99C3 /* Function.h */,
     
    14191422                                1A1D8B9C173186CE00141DA4 /* FunctionDispatcher.h in Headers */,
    14201423                                A8A473CA151A825B004123FF /* GetPtr.h in Headers */,
     1424                                FE86A8751E59440200111BBF /* ForbidHeapAllocation.h in Headers */,
    14211425                                0FEC84AF1BD825310080FF74 /* GraphNodeWorklist.h in Headers */,
    14221426                                2C05385415BC819000F21B96 /* GregorianDateTime.h in Headers */,
Note: See TracChangeset for help on using the changeset viewer.