Changeset 215919 in webkit


Ignore:
Timestamp:
Apr 27, 2017, 9:15:00 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

Fix some RELEASE_ASSERT failures caused by OutOfMemoryErrors.
https://bugs.webkit.org/show_bug.cgi?id=171404
<rdar://problem/31876178>

Reviewed by Saam Barati.

JSTests:

  • stress/js-fixed-array-out-of-memory.js: Added.

Source/JavaScriptCore:

  1. Added some tryAllocate() functions in JSCellInlines.h.
  2. Consolidated the implementations of allocateCell() template functions into a single tryAllocateCellHelper() to reduce redundancy and eliminate needing to copy-paste for variations of allocateCell and tryAllocateCell.
  3. Changed JSFixedArray::createFromArray() and constructEmptyArray() to check for allocation failure and throw an OutOfMemoryError. It was already possible to throw errors from these functions for other reasons. So, their clients are already ready to handle OOMEs.
  • ftl/FTLOperations.cpp:

(JSC::FTL::operationMaterializeObjectInOSR):

  • runtime/JSCInlines.h:
  • runtime/JSCell.h:
  • runtime/JSCellInlines.h:

(JSC::tryAllocateCellHelper):
(JSC::allocateCell):
(JSC::tryAllocateCell):

  • runtime/JSFixedArray.h:

(JSC::JSFixedArray::createFromArray):
(JSC::JSFixedArray::tryCreate):
(JSC::JSFixedArray::create): Deleted.

  • runtime/JSGlobalObject.h:

(JSC::constructEmptyArray):

Location:
trunk
Files:
1 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r215894 r215919  
     12017-04-27  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix some RELEASE_ASSERT failures caused by OutOfMemoryErrors.
     4        https://bugs.webkit.org/show_bug.cgi?id=171404
     5        <rdar://problem/31876178>
     6
     7        Reviewed by Saam Barati.
     8
     9        * stress/js-fixed-array-out-of-memory.js: Added.
     10
    1112017-04-27  David Kilzer  <ddkilzer@apple.com>
    212
  • trunk/Source/JavaScriptCore/ChangeLog

    r215916 r215919  
     12017-04-27  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix some RELEASE_ASSERT failures caused by OutOfMemoryErrors.
     4        https://bugs.webkit.org/show_bug.cgi?id=171404
     5        <rdar://problem/31876178>
     6
     7        Reviewed by Saam Barati.
     8
     9        1. Added some tryAllocate() functions in JSCellInlines.h.
     10        2. Consolidated the implementations of allocateCell() template functions into a
     11           single tryAllocateCellHelper() to reduce redundancy and eliminate needing to
     12           copy-paste for variations of allocateCell and tryAllocateCell.
     13        3. Changed JSFixedArray::createFromArray() and constructEmptyArray() to check for
     14           allocation failure and throw an OutOfMemoryError.  It was already possible to
     15           throw errors from these functions for other reasons.  So, their clients are
     16           already ready to handle OOMEs.
     17
     18        * ftl/FTLOperations.cpp:
     19        (JSC::FTL::operationMaterializeObjectInOSR):
     20        * runtime/JSCInlines.h:
     21        * runtime/JSCell.h:
     22        * runtime/JSCellInlines.h:
     23        (JSC::tryAllocateCellHelper):
     24        (JSC::allocateCell):
     25        (JSC::tryAllocateCell):
     26        * runtime/JSFixedArray.h:
     27        (JSC::JSFixedArray::createFromArray):
     28        (JSC::JSFixedArray::tryCreate):
     29        (JSC::JSFixedArray::create): Deleted.
     30        * runtime/JSGlobalObject.h:
     31        (JSC::constructEmptyArray):
     32
    1332017-04-27  Joseph Pecoraro  <pecoraro@apple.com>
    234
  • trunk/Source/JavaScriptCore/ftl/FTLOperations.cpp

    r215885 r215919  
    433433        // Any attempts to put a getter on any indices on the rest array will escape the array.
    434434        JSFixedArray* fixedArray = JSFixedArray::createFromArray(exec, vm, array);
     435        RELEASE_ASSERT(fixedArray);
    435436        return fixedArray;
    436437    }
  • trunk/Source/JavaScriptCore/runtime/JSCInlines.h

    r208637 r215919  
    11/*
    2  * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343#include "JSArrayBufferViewInlines.h"
    4444#include "JSCJSValueInlines.h"
     45#include "JSCellInlines.h"
    4546#include "JSFunctionInlines.h"
    4647#include "JSGlobalObjectInlines.h"
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r214905 r215919  
    5151class Structure;
    5252
    53 template<typename T> void* allocateCell(Heap&);
    54 template<typename T> void* allocateCell(Heap&, size_t);
    55 
    56 template<typename T> void* allocateCell(Heap&, GCDeferralContext*);
    57 template<typename T> void* allocateCell(Heap&, GCDeferralContext*, size_t);
     53enum class AllocationFailureMode {
     54    ShouldAssertOnFailure,
     55    ShouldNotAssertOnFailure
     56};
     57
     58enum class GCDeferralContextArgPresense {
     59    HasArg,
     60    DoesNotHaveArg
     61};
     62
     63template<typename T> void* allocateCell(Heap&, size_t = sizeof(T));
     64template<typename T> void* tryAllocateCell(Heap&, size_t = sizeof(T));
     65template<typename T> void* allocateCell(Heap&, GCDeferralContext*, size_t = sizeof(T));
     66template<typename T> void* tryAllocateCell(Heap&, GCDeferralContext*, size_t = sizeof(T));
    5867
    5968#define DECLARE_EXPORT_INFO                                                  \
     
    7281    friend class JSValue;
    7382    friend class MarkedBlock;
    74     template<typename T> friend void* allocateCell(Heap&);
    75     template<typename T> friend void* allocateCell(Heap&, size_t);
    76     template<typename T> friend void* allocateCell(Heap&, GCDeferralContext*);
    77     template<typename T> friend void* allocateCell(Heap&, GCDeferralContext*, size_t);
     83    template<typename T, AllocationFailureMode, GCDeferralContextArgPresense>
     84    friend void* tryAllocateCellHelper(Heap&, GCDeferralContext*, size_t);
    7885
    7986public:
  • trunk/Source/JavaScriptCore/runtime/JSCellInlines.h

    r215885 r215919  
    143143}
    144144
    145 template<typename T>
    146 void* allocateCell(Heap& heap, size_t size)
    147 {
    148     ASSERT(!DisallowGC::isInEffectOnCurrentThread());
     145template<typename T, AllocationFailureMode mode, GCDeferralContextArgPresense deferralContextArgPresence>
     146ALWAYS_INLINE void* tryAllocateCellHelper(Heap& heap, GCDeferralContext* deferralContext, size_t size)
     147{
     148    ASSERT(deferralContext || !DisallowGC::isInEffectOnCurrentThread());
    149149    ASSERT(size >= sizeof(T));
    150     JSCell* result = static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(size));
     150    JSCell* result;
     151    if (mode == AllocationFailureMode::ShouldAssertOnFailure) {
     152        result = (deferralContextArgPresence == GCDeferralContextArgPresense::HasArg)
     153            ? static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(deferralContext, size))
     154            : static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(size));
     155    } else {
     156        result = (deferralContextArgPresence == GCDeferralContextArgPresense::HasArg)
     157            ? static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->tryAllocate(deferralContext, size))
     158            : static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->tryAllocate(size));
     159        if (UNLIKELY(!result))
     160            return nullptr;
     161    }
    151162#if ENABLE(GC_VALIDATION)
    152163    ASSERT(!heap.vm()->isInitializingObject());
     
    156167    return result;
    157168}
    158    
     169
    159170template<typename T>
    160 void* allocateCell(Heap& heap)
    161 {
    162     return allocateCell<T>(heap, sizeof(T));
    163 }
    164    
     171void* allocateCell(Heap& heap, size_t size)
     172{
     173    return tryAllocateCellHelper<T, AllocationFailureMode::ShouldAssertOnFailure, GCDeferralContextArgPresense::DoesNotHaveArg>(heap, nullptr, size);
     174}
     175
     176template<typename T>
     177void* tryAllocateCell(Heap& heap, size_t size)
     178{
     179    return tryAllocateCellHelper<T, AllocationFailureMode::ShouldNotAssertOnFailure, GCDeferralContextArgPresense::DoesNotHaveArg>(heap, nullptr, size);
     180}
     181
    165182template<typename T>
    166183void* allocateCell(Heap& heap, GCDeferralContext* deferralContext, size_t size)
    167184{
    168     ASSERT(size >= sizeof(T));
    169     JSCell* result = static_cast<JSCell*>(subspaceFor<T>(*heap.vm())->allocate(deferralContext, size));
    170 #if ENABLE(GC_VALIDATION)
    171     ASSERT(!heap.vm()->isInitializingObject());
    172     heap.vm()->setInitializingObjectClass(T::info());
    173 #endif
    174     result->clearStructure();
    175     return result;
    176 }
    177    
     185    return tryAllocateCellHelper<T, AllocationFailureMode::ShouldAssertOnFailure, GCDeferralContextArgPresense::HasArg>(heap, deferralContext, size);
     186}
     187
    178188template<typename T>
    179 void* allocateCell(Heap& heap, GCDeferralContext* deferralContext)
    180 {
    181     return allocateCell<T>(heap, deferralContext, sizeof(T));
    182 }
    183    
     189void* tryAllocateCell(Heap& heap, GCDeferralContext* deferralContext, size_t size)
     190{
     191    return tryAllocateCellHelper<T, AllocationFailureMode::ShouldNotAssertOnFailure, GCDeferralContextArgPresense::HasArg>(heap, deferralContext, size);
     192}
     193
    184194inline bool JSCell::isObject() const
    185195{
  • trunk/Source/JavaScriptCore/runtime/JSFixedArray.h

    r215720 r215919  
    4646    ALWAYS_INLINE static JSFixedArray* createFromArray(ExecState* exec, VM& vm, JSArray* array)
    4747    {
     48        auto throwScope = DECLARE_THROW_SCOPE(vm);
     49
    4850        IndexingType indexingType = array->indexingType() & IndexingShapeMask;
    4951        unsigned length = array->length();
    50         JSFixedArray* result = JSFixedArray::create(vm, vm.fixedArrayStructure.get(), length);
     52        JSFixedArray* result = JSFixedArray::tryCreate(vm, vm.fixedArrayStructure.get(), length);
     53        if (UNLIKELY(!result)) {
     54            throwOutOfMemoryError(exec, throwScope);
     55            return nullptr;
     56        }
    5157
    5258        if (!length)
     
    7177        }
    7278
    73 
    74         auto throwScope = DECLARE_THROW_SCOPE(vm);
    7579        for (unsigned i = 0; i < length; i++) {
    7680            JSValue value = array->getDirectIndex(exec, i);
     
    117121    unsigned m_size;
    118122
    119     ALWAYS_INLINE static JSFixedArray* create(VM& vm, Structure* structure, unsigned size)
     123    ALWAYS_INLINE static JSFixedArray* tryCreate(VM& vm, Structure* structure, unsigned size)
    120124    {
    121         JSFixedArray* result = new (NotNull, allocateCell<JSFixedArray>(vm.heap, allocationSize(size))) JSFixedArray(vm, structure, size);
     125        void* buffer = tryAllocateCell<JSFixedArray>(vm.heap, allocationSize(size));
     126        if (UNLIKELY(!buffer))
     127            return nullptr;
     128        JSFixedArray* result = new (NotNull, buffer) JSFixedArray(vm, structure, size);
    122129        result->finishCreation(vm);
    123130        return result;
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r215916 r215919  
    11/*
    22 *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
    3  *  Copyright (C) 2007-2009, 2014-2016 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2007-2017 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    2424#include "ArrayAllocationProfile.h"
    2525#include "ArrayBufferSharingMode.h"
     26#include "ExceptionHelpers.h"
    2627#include "InternalFunction.h"
    2728#include "JSArray.h"
     
    875876    RETURN_IF_EXCEPTION(scope, nullptr);
    876877
    877     return ArrayAllocationProfile::updateLastAllocationFor(profile, JSArray::create(exec->vm(), structure, initialLength));
     878    JSArray* result = JSArray::tryCreate(vm, structure, initialLength);
     879    if (UNLIKELY(!result)) {
     880        throwOutOfMemoryError(exec, scope);
     881        return nullptr;
     882    }
     883    return ArrayAllocationProfile::updateLastAllocationFor(profile, result);
    878884}
    879885
Note: See TracChangeset for help on using the changeset viewer.