diff --git a/API/APICast.h b/API/APICast.h index 8fe8d60..21f3a7d 100644 --- a/API/APICast.h +++ b/API/APICast.h @@ -60,6 +60,11 @@ inline JSC::ExecState* toJS(JSGlobalContextRef c) return reinterpret_cast(c); } +inline JSC::JSGlobalObject* toJSGlobalObject(JSGlobalContextRef context) +{ + return toJS(context)->lexicalGlobalObject(); +} + inline JSC::JSValue toJS(JSC::ExecState* exec, JSValueRef v) { ASSERT_UNUSED(exec, exec); diff --git a/API/APIUtils.h b/API/APIUtils.h index e2190c8..782a915 100644 --- a/API/APIUtils.h +++ b/API/APIUtils.h @@ -26,6 +26,7 @@ #ifndef APIUtils_h #define APIUtils_h +#include "CatchScope.h" #include "Exception.h" #include "JSCJSValue.h" #include "JSGlobalObjectInspectorController.h" diff --git a/API/JSAPIWrapperObject.mm b/API/JSAPIWrapperObject.mm index f301d3e..46dc2a7 100644 --- a/API/JSAPIWrapperObject.mm +++ b/API/JSAPIWrapperObject.mm @@ -68,7 +68,7 @@ bool JSAPIWrapperObjectHandleOwner::isReachableFromOpaqueRoots(JSC::Handle const ClassInfo JSCallbackObject::s_info = { "JSAPIWrapperObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; +template <> const ClassInfo JSCallbackObject::s_info = { "JSAPIWrapperObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCallbackObject) }; template<> const bool JSCallbackObject::needsDestruction = true; diff --git a/API/JSBase.cpp b/API/JSBase.cpp index a3e2059..d8917a3 100644 --- a/API/JSBase.cpp +++ b/API/JSBase.cpp @@ -62,7 +62,8 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th // evaluate sets "this" to the global object if it is NULL JSGlobalObject* globalObject = exec->vmEntryGlobalObject(); - SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); + auto sourceURLString = sourceURL ? sourceURL->string() : String(); + SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); NakedPtr evaluationException; JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException); @@ -99,7 +100,8 @@ bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourc startingLineNumber = std::max(1, startingLineNumber); - SourceCode source = makeSource(script->string(), sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); + auto sourceURLString = sourceURL ? sourceURL->string() : String(); + SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); JSValue syntaxException; bool isValidSyntax = checkSyntax(exec->vmEntryGlobalObject()->globalExec(), source, &syntaxException); @@ -155,7 +157,7 @@ void JSSynchronousGarbageCollectForDebugging(JSContextRef ctx) ExecState* exec = toJS(ctx); JSLockHolder locker(exec); - exec->vm().heap.collectAllGarbage(); + exec->vm().heap.collectNow(Sync, CollectionScope::Full); } void JSSynchronousEdenCollectForDebugging(JSContextRef ctx) diff --git a/API/JSBase.h b/API/JSBase.h index bc85aca..677dff1 100644 --- a/API/JSBase.h +++ b/API/JSBase.h @@ -138,7 +138,11 @@ JS_EXPORT void JSGarbageCollect(JSContextRef ctx); /* Enable the Objective-C API for platforms with a modern runtime. */ #if !defined(JSC_OBJC_API_ENABLED) -#define JSC_OBJC_API_ENABLED (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE))) +#if (defined(__clang__) && defined(__APPLE__) && ((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && !defined(__i386__)) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE))) +#define JSC_OBJC_API_ENABLED 1 +#else +#define JSC_OBJC_API_ENABLED 0 +#endif #endif #endif /* JSBase_h */ diff --git a/API/JSCallbackConstructor.cpp b/API/JSCallbackConstructor.cpp index 5597c3e..57e80a8 100644 --- a/API/JSCallbackConstructor.cpp +++ b/API/JSCallbackConstructor.cpp @@ -36,7 +36,7 @@ namespace JSC { -const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackConstructor) }; +const ClassInfo JSCallbackConstructor::s_info = { "CallbackConstructor", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCallbackConstructor) }; JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Structure* structure, JSClassRef jsClass, JSObjectCallAsConstructorCallback callback) : JSDestructibleObject(globalObject->vm(), structure) @@ -48,7 +48,7 @@ JSCallbackConstructor::JSCallbackConstructor(JSGlobalObject* globalObject, Struc void JSCallbackConstructor::finishCreation(JSGlobalObject* globalObject, JSClassRef jsClass) { Base::finishCreation(globalObject->vm()); - ASSERT(inherits(info())); + ASSERT(inherits(*vm(), info())); if (m_class) JSClassRetain(jsClass); } diff --git a/API/JSCallbackFunction.cpp b/API/JSCallbackFunction.cpp index 57333f5..684ece6 100644 --- a/API/JSCallbackFunction.cpp +++ b/API/JSCallbackFunction.cpp @@ -41,7 +41,7 @@ namespace JSC { STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSCallbackFunction); -const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, 0, CREATE_METHOD_TABLE(JSCallbackFunction) }; +const ClassInfo JSCallbackFunction::s_info = { "CallbackFunction", &InternalFunction::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCallbackFunction) }; JSCallbackFunction::JSCallbackFunction(VM& vm, Structure* structure, JSObjectCallAsFunctionCallback callback) : InternalFunction(vm, structure) @@ -52,7 +52,7 @@ JSCallbackFunction::JSCallbackFunction(VM& vm, Structure* structure, JSObjectCal void JSCallbackFunction::finishCreation(VM& vm, const String& name) { Base::finishCreation(vm, name); - ASSERT(inherits(info())); + ASSERT(inherits(vm, info())); } JSCallbackFunction* JSCallbackFunction::create(VM& vm, JSGlobalObject* globalObject, JSObjectCallAsFunctionCallback callback, const String& name) diff --git a/API/JSCallbackObject.cpp b/API/JSCallbackObject.cpp index 02b38fd..cb63f49 100644 --- a/API/JSCallbackObject.cpp +++ b/API/JSCallbackObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Inc. All rights reserved. + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. * Copyright (C) 2007 Eric Seidel * * Redistribution and use in source and binary forms, with or without @@ -34,8 +34,8 @@ namespace JSC { // Define the two types of JSCallbackObjects we support. -template <> const ClassInfo JSCallbackObject::s_info = { "CallbackObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; -template <> const ClassInfo JSCallbackObject::s_info = { "CallbackGlobalObject", &Base::s_info, 0, CREATE_METHOD_TABLE(JSCallbackObject) }; +template <> const ClassInfo JSCallbackObject::s_info = { "CallbackObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCallbackObject) }; +template <> const ClassInfo JSCallbackObject::s_info = { "CallbackGlobalObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCallbackObject) }; template<> const bool JSCallbackObject::needsDestruction = true; template<> const bool JSCallbackObject::needsDestruction = false; @@ -45,7 +45,6 @@ JSCallbackObject* JSCallbackObject::create(VM& v { JSCallbackObject* callbackObject = new (NotNull, allocateCell>(vm.heap)) JSCallbackObject(vm, classRef, structure); callbackObject->finishCreation(vm); - vm.heap.addFinalizer(callbackObject, destroy); return callbackObject; } diff --git a/API/JSCallbackObject.h b/API/JSCallbackObject.h index 2525982..43749e2 100644 --- a/API/JSCallbackObject.h +++ b/API/JSCallbackObject.h @@ -106,9 +106,9 @@ public: void visitChildren(SlotVisitor& visitor) { LockHolder locker(m_lock); - for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) { - if (ptr->value) - visitor.append(ptr->value); + for (auto& pair : m_propertyMap) { + if (pair.value) + visitor.append(pair.value); } } diff --git a/API/JSCallbackObjectFunctions.h b/API/JSCallbackObjectFunctions.h index a525f5b..ee3ee2f 100644 --- a/API/JSCallbackObjectFunctions.h +++ b/API/JSCallbackObjectFunctions.h @@ -44,15 +44,16 @@ namespace JSC { template inline JSCallbackObject* JSCallbackObject::asCallbackObject(JSValue value) { - ASSERT(asObject(value)->inherits(info())); + ASSERT(asObject(value)->inherits(*value.getObject()->vm(), info())); return jsCast(asObject(value)); } template -inline JSCallbackObject* JSCallbackObject::asCallbackObject(EncodedJSValue value) +inline JSCallbackObject* JSCallbackObject::asCallbackObject(EncodedJSValue encodedValue) { - ASSERT(asObject(JSValue::decode(value))->inherits(info())); - return jsCast(asObject(JSValue::decode(value))); + JSValue value = JSValue::decode(encodedValue); + ASSERT(asObject(value)->inherits(*value.getObject()->vm(), info())); + return jsCast(asObject(value)); } template @@ -90,8 +91,9 @@ JSCallbackObject::~JSCallbackObject() template void JSCallbackObject::finishCreation(ExecState* exec) { - Base::finishCreation(exec->vm()); - ASSERT(Parent::inherits(info())); + VM& vm = exec->vm(); + Base::finishCreation(vm); + ASSERT(Parent::inherits(vm, info())); init(exec); } @@ -99,7 +101,7 @@ void JSCallbackObject::finishCreation(ExecState* exec) template void JSCallbackObject::finishCreation(VM& vm) { - ASSERT(Parent::inherits(info())); + ASSERT(Parent::inherits(vm, info())); ASSERT(Parent::isGlobalObject()); Base::finishCreation(vm); init(jsCast(this)->globalExec()); diff --git a/API/JSContext.mm b/API/JSContext.mm index 3291622..5b100c7 100644 --- a/API/JSContext.mm +++ b/API/JSContext.mm @@ -43,17 +43,22 @@ @implementation JSContext { JSVirtualMachine *m_virtualMachine; JSGlobalContextRef m_context; - JSWrapperMap *m_wrapperMap; JSC::Strong m_exception; } -@synthesize exceptionHandler; - - (JSGlobalContextRef)JSGlobalContextRef { return m_context; } +- (void)ensureWrapperMap +{ + if (!toJS([self JSGlobalContextRef])->lexicalGlobalObject()->wrapperMap()) { + // The map will be retained by the GlobalObject in initialization. + [[[JSWrapperMap alloc] initWithGlobalContextRef:[self JSGlobalContextRef]] release]; + } +} + - (instancetype)init { return [self initWithVirtualMachine:[[[JSVirtualMachine alloc] init] autorelease]]; @@ -67,12 +72,12 @@ m_virtualMachine = [virtualMachine retain]; m_context = JSGlobalContextCreateInGroup(getGroupFromVirtualMachine(virtualMachine), 0); - m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self]; self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; }; + [self ensureWrapperMap]; [m_virtualMachine addContext:self forGlobalContextRef:m_context]; return self; @@ -81,10 +86,9 @@ - (void)dealloc { m_exception.clear(); - [m_wrapperMap release]; JSGlobalContextRelease(m_context); [m_virtualMachine release]; - [self.exceptionHandler release]; + [_exceptionHandler release]; [super dealloc]; } @@ -127,7 +131,7 @@ - (JSWrapperMap *)wrapperMap { - return m_wrapperMap; + return toJS(m_context)->lexicalGlobalObject()->wrapperMap(); } - (JSValue *)globalObject @@ -260,7 +264,7 @@ m_virtualMachine = [[JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&globalObject->vm())] retain]; ASSERT(m_virtualMachine); m_context = JSGlobalContextRetain(context); - m_wrapperMap = [[JSWrapperMap alloc] initWithContext:self]; + [self ensureWrapperMap]; self.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) { context.exception = exceptionValue; @@ -311,13 +315,13 @@ - (JSValue *)wrapperForObjCObject:(id)object { JSC::JSLockHolder locker(toJS(m_context)); - return [m_wrapperMap jsWrapperForObject:object]; + return [[self wrapperMap] jsWrapperForObject:object inContext:self]; } - (JSValue *)wrapperForJSObject:(JSValueRef)value { JSC::JSLockHolder locker(toJS(m_context)); - return [m_wrapperMap objcWrapperForJSValueRef:value]; + return [[self wrapperMap] objcWrapperForJSValueRef:value inContext:self]; } + (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext diff --git a/API/JSContextInternal.h b/API/JSContextInternal.h index 5308fbb..b37cfa4 100644 --- a/API/JSContextInternal.h +++ b/API/JSContextInternal.h @@ -59,7 +59,7 @@ private: @interface JSContext(Internal) -- (id)initWithGlobalContextRef:(JSGlobalContextRef)context; +- (instancetype)initWithGlobalContextRef:(JSGlobalContextRef)context; - (void)notifyException:(JSValueRef)exception; - (JSValue *)valueFromNotifyException:(JSValueRef)exception; diff --git a/API/JSContextRef.cpp b/API/JSContextRef.cpp index 13769df..541cb70 100644 --- a/API/JSContextRef.cpp +++ b/API/JSContextRef.cpp @@ -133,12 +133,12 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass { initializeThreading(); - RefPtr vm = group ? PassRefPtr(toJS(group)) : VM::createContextGroup(); + Ref vm = group ? Ref(*toJS(group)) : VM::createContextGroup(); - JSLockHolder locker(vm.get()); + JSLockHolder locker(vm.ptr()); if (!globalObjectClass) { - JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull())); + JSGlobalObject* globalObject = JSGlobalObject::create(vm.get(), JSGlobalObject::createStructure(vm.get(), jsNull())); #if ENABLE(REMOTE_INSPECTOR) if (JSRemoteInspectorGetInspectionEnabledByDefault()) globalObject->setRemoteDebuggingEnabled(true); @@ -146,12 +146,12 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec())); } - JSGlobalObject* globalObject = JSCallbackObject::create(*vm, globalObjectClass, JSCallbackObject::createStructure(*vm, 0, jsNull())); + JSGlobalObject* globalObject = JSCallbackObject::create(vm.get(), globalObjectClass, JSCallbackObject::createStructure(vm.get(), 0, jsNull())); ExecState* exec = globalObject->globalExec(); JSValue prototype = globalObjectClass->prototype(exec); if (!prototype) prototype = jsNull(); - globalObject->resetPrototype(*vm, prototype); + globalObject->resetPrototype(vm.get(), prototype); #if ENABLE(REMOTE_INSPECTOR) if (JSRemoteInspectorGetInspectionEnabledByDefault()) globalObject->setRemoteDebuggingEnabled(true); @@ -260,9 +260,11 @@ public: if (m_remainingCapacityForFrameCapture) { // If callee is unknown, but we've not added any frame yet, we should // still add the frame, because something called us, and gave us arguments. - JSCell* callee = visitor->callee(); - if (!callee && visitor->index()) - return StackVisitor::Done; + if (visitor->callee().isCell()) { + JSCell* callee = visitor->callee().asCell(); + if (!callee && visitor->index()) + return StackVisitor::Done; + } StringBuilder& builder = m_builder; if (!builder.isEmpty()) @@ -281,7 +283,7 @@ public: builder.appendNumber(lineNumber); } - if (!callee) + if (!visitor->callee().rawPtr()) return StackVisitor::Done; m_remainingCapacityForFrameCapture--; diff --git a/API/JSHeapFinalizerPrivate.cpp b/API/JSHeapFinalizerPrivate.cpp new file mode 100644 index 0000000..012dc4f --- /dev/null +++ b/API/JSHeapFinalizerPrivate.cpp @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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 "JSHeapFinalizerPrivate.h" + +#include "APICast.h" +#include "JSCInlines.h" + +using namespace JSC; + +void JSContextGroupAddHeapFinalizer(JSContextGroupRef group, JSHeapFinalizer finalizer, void *userData) +{ + VM* vm = toJS(group); + JSLockHolder locker(vm); + vm->heap.addHeapFinalizerCallback(HeapFinalizerCallback(finalizer, userData)); +} + +void JSContextGroupRemoveHeapFinalizer(JSContextGroupRef group, JSHeapFinalizer finalizer, void *userData) +{ + VM* vm = toJS(group); + JSLockHolder locker(vm); + vm->heap.removeHeapFinalizerCallback(HeapFinalizerCallback(finalizer, userData)); +} diff --git a/API/JSHeapFinalizerPrivate.h b/API/JSHeapFinalizerPrivate.h new file mode 100644 index 0000000..8c9b152 --- /dev/null +++ b/API/JSHeapFinalizerPrivate.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. + */ + +#ifndef JSHeapFinalizerPrivate_h +#define JSHeapFinalizerPrivate_h + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*JSHeapFinalizer)(JSContextGroupRef, void *userData); + +JS_EXPORT void JSContextGroupAddHeapFinalizer(JSContextGroupRef, JSHeapFinalizer, void *userData); +JS_EXPORT void JSContextGroupRemoveHeapFinalizer(JSContextGroupRef, JSHeapFinalizer, void *userData); + +#ifdef __cplusplus +} +#endif + +#endif // JSHeapFinalizerPrivate_h + diff --git a/API/JSMarkingConstraintPrivate.cpp b/API/JSMarkingConstraintPrivate.cpp new file mode 100644 index 0000000..17074e4 --- /dev/null +++ b/API/JSMarkingConstraintPrivate.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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 "JSMarkingConstraintPrivate.h" + +#include "APICast.h" +#include "JSCInlines.h" +#include "MarkingConstraint.h" +#include "VisitingTimeout.h" + +using namespace JSC; + +namespace { + +Atomic constraintCounter; + +struct Marker : JSMarker { + SlotVisitor* visitor; +}; + +bool isMarked(JSMarkerRef, JSObjectRef objectRef) +{ + if (!objectRef) + return true; // Null is an immortal object. + + return Heap::isMarked(toJS(objectRef)); +} + +void mark(JSMarkerRef markerRef, JSObjectRef objectRef) +{ + if (!objectRef) + return; + + static_cast(markerRef)->visitor->appendHiddenUnbarriered(toJS(objectRef)); +} + +} // anonymous namespace + +void JSContextGroupAddMarkingConstraint(JSContextGroupRef group, JSMarkingConstraint constraintCallback, void *userData) +{ + VM& vm = *toJS(group); + JSLockHolder locker(vm); + + unsigned constraintIndex = constraintCounter.exchangeAdd(1); + + // This is a guess. The algorithm should be correct no matter what we pick. This means + // that we expect this constraint to mark things even during a stop-the-world full GC, but + // we don't expect it to be able to mark anything at the very start of a GC before anything + // else gets marked. + ConstraintVolatility volatility = ConstraintVolatility::GreyedByMarking; + + auto constraint = std::make_unique( + toCString("Amc", constraintIndex, "(", RawPointer(bitwise_cast(constraintCallback)), ")"), + toCString("API Marking Constraint #", constraintIndex, " (", RawPointer(bitwise_cast(constraintCallback)), ", ", RawPointer(userData), ")"), + [constraintCallback, userData] + (SlotVisitor& slotVisitor, const VisitingTimeout&) { + Marker marker; + marker.IsMarked = isMarked; + marker.Mark = mark; + marker.visitor = &slotVisitor; + + constraintCallback(&marker, userData); + }, + volatility); + + vm.heap.addMarkingConstraint(WTFMove(constraint)); +} diff --git a/API/JSMarkingConstraintPrivate.h b/API/JSMarkingConstraintPrivate.h new file mode 100644 index 0000000..aaf85ca --- /dev/null +++ b/API/JSMarkingConstraintPrivate.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. + */ + +#ifndef JSMarkingConstraintPrivate_h +#define JSMarkingConstraintPrivate_h + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct JSMarker; +typedef struct JSMarker JSMarker; +typedef JSMarker *JSMarkerRef; + +struct JSMarker { + bool (*IsMarked)(JSMarkerRef, JSObjectRef); + void (*Mark)(JSMarkerRef, JSObjectRef); +}; + +typedef void (*JSMarkingConstraint)(JSMarkerRef, void *userData); + +JS_EXPORT void JSContextGroupAddMarkingConstraint(JSContextGroupRef, JSMarkingConstraint, void *userData); + +#ifdef __cplusplus +} +#endif + +#endif // JSMarkingConstraintPrivate_h + diff --git a/API/JSObjectRef.cpp b/API/JSObjectRef.cpp index 87e7c77..cefef66 100644 --- a/API/JSObjectRef.cpp +++ b/API/JSObjectRef.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007, 2008, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. * Copyright (C) 2008 Kelvin W Sherlock (ksherlock@gmail.com) * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include "ObjectConstructor.h" #include "ObjectPrototype.h" #include "PropertyNameArray.h" +#include "ProxyObject.h" #include "RegExpConstructor.h" #if ENABLE(REMOTE_INSPECTOR) @@ -146,7 +147,8 @@ JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned pa args.append(jsString(exec, parameterNames[i]->string())); args.append(jsString(exec, body->string())); - JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, sourceURL ? sourceURL->string() : String(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); + auto sourceURLString = sourceURL ? sourceURL->string() : String(); + JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); if (handleExceptionIfNeeded(exec, exception) == ExceptionStatus::DidThrow) result = 0; return toRef(result); @@ -256,13 +258,14 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value return; } ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); JSValue jsValue = toJS(exec, value); - if (JSProxy* proxy = jsDynamicCast(jsObject)) { - if (JSGlobalObject* globalObject = jsDynamicCast(proxy->target())) { + if (JSProxy* proxy = jsDynamicCast(vm, jsObject)) { + if (JSGlobalObject* globalObject = jsDynamicCast(vm, proxy->target())) { globalObject->resetPrototype(exec->vm(), jsValue.isObject() ? jsValue : jsNull()); return; } @@ -384,24 +387,25 @@ bool JSObjectDeleteProperty(JSContextRef ctx, JSObjectRef object, JSStringRef pr // during destruction. static const ClassInfo* classInfoPrivate(JSObject* jsObject) { - VM* vm = jsObject->vm(); + VM& vm = *jsObject->vm(); - if (vm->currentlyDestructingCallbackObject != jsObject) - return jsObject->classInfo(); + if (vm.currentlyDestructingCallbackObject != jsObject) + return jsObject->classInfo(vm); - return vm->currentlyDestructingCallbackObjectClassInfo; + return vm.currentlyDestructingCallbackObjectClassInfo; } void* JSObjectGetPrivate(JSObjectRef object) { JSObject* jsObject = uncheckedToJS(object); + VM& vm = *jsObject->vm(); const ClassInfo* classInfo = classInfoPrivate(jsObject); // Get wrapped object if proxied if (classInfo->isSubClassOf(JSProxy::info())) { jsObject = static_cast(jsObject)->target(); - classInfo = jsObject->classInfo(); + classInfo = jsObject->classInfo(vm); } if (classInfo->isSubClassOf(JSCallbackObject::info())) @@ -419,13 +423,14 @@ void* JSObjectGetPrivate(JSObjectRef object) bool JSObjectSetPrivate(JSObjectRef object, void* data) { JSObject* jsObject = uncheckedToJS(object); + VM& vm = *jsObject->vm(); const ClassInfo* classInfo = classInfoPrivate(jsObject); // Get wrapped object if proxied if (classInfo->isSubClassOf(JSProxy::info())) { jsObject = static_cast(jsObject)->target(); - classInfo = jsObject->classInfo(); + classInfo = jsObject->classInfo(vm); } if (classInfo->isSubClassOf(JSCallbackObject::info())) { @@ -449,21 +454,23 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data) JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); JSValue result; Identifier name(propertyName->identifier(&exec->vm())); + // Get wrapped object if proxied - if (jsObject->inherits(JSProxy::info())) + if (jsObject->inherits(vm, JSProxy::info())) jsObject = jsCast(jsObject)->target(); - if (jsObject->inherits(JSCallbackObject::info())) + if (jsObject->inherits(vm, JSCallbackObject::info())) result = jsCast*>(jsObject)->getPrivateProperty(name); - else if (jsObject->inherits(JSCallbackObject::info())) + else if (jsObject->inherits(vm, JSCallbackObject::info())) result = jsCast*>(jsObject)->getPrivateProperty(name); #if JSC_OBJC_API_ENABLED - else if (jsObject->inherits(JSCallbackObject::info())) + else if (jsObject->inherits(vm, JSCallbackObject::info())) result = jsCast*>(jsObject)->getPrivateProperty(name); #endif return toRef(exec, result); @@ -472,25 +479,26 @@ JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSSt bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); JSValue jsValue = value ? toJS(exec, value) : JSValue(); Identifier name(propertyName->identifier(&exec->vm())); // Get wrapped object if proxied - if (jsObject->inherits(JSProxy::info())) + if (jsObject->inherits(vm, JSProxy::info())) jsObject = jsCast(jsObject)->target(); - if (jsObject->inherits(JSCallbackObject::info())) { + if (jsObject->inherits(vm, JSCallbackObject::info())) { jsCast*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue); return true; } - if (jsObject->inherits(JSCallbackObject::info())) { + if (jsObject->inherits(vm, JSCallbackObject::info())) { jsCast*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue); return true; } #if JSC_OBJC_API_ENABLED - if (jsObject->inherits(JSCallbackObject::info())) { + if (jsObject->inherits(vm, JSCallbackObject::info())) { jsCast*>(jsObject)->setPrivateProperty(exec->vm(), name, jsValue); return true; } @@ -501,24 +509,25 @@ bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRe bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* jsObject = toJS(object); Identifier name(propertyName->identifier(&exec->vm())); // Get wrapped object if proxied - if (jsObject->inherits(JSProxy::info())) + if (jsObject->inherits(vm, JSProxy::info())) jsObject = jsCast(jsObject)->target(); - if (jsObject->inherits(JSCallbackObject::info())) { + if (jsObject->inherits(vm, JSCallbackObject::info())) { jsCast*>(jsObject)->deletePrivateProperty(name); return true; } - if (jsObject->inherits(JSCallbackObject::info())) { + if (jsObject->inherits(vm, JSCallbackObject::info())) { jsCast*>(jsObject)->deletePrivateProperty(name); return true; } #if JSC_OBJC_API_ENABLED - if (jsObject->inherits(JSCallbackObject::info())) { + if (jsObject->inherits(vm, JSCallbackObject::info())) { jsCast*>(jsObject)->deletePrivateProperty(name); return true; } @@ -667,3 +676,18 @@ void JSPropertyNameAccumulatorAddName(JSPropertyNameAccumulatorRef array, JSStri JSLockHolder locker(propertyNames->vm()); propertyNames->add(propertyName->identifier(propertyNames->vm())); } + +JSObjectRef JSObjectGetProxyTarget(JSObjectRef objectRef) +{ + JSObject* object = toJS(objectRef); + if (!object) + return nullptr; + VM& vm = *object->vm(); + JSLockHolder locker(vm); + JSObject* result = nullptr; + if (JSProxy* proxy = jsDynamicCast(vm, object)) + result = proxy->target(); + else if (ProxyObject* proxy = jsDynamicCast(vm, object)) + result = proxy->target(); + return toRef(result); +} diff --git a/API/JSObjectRefPrivate.h b/API/JSObjectRefPrivate.h index 32e80ab..e2bdad6 100644 --- a/API/JSObjectRefPrivate.h +++ b/API/JSObjectRefPrivate.h @@ -67,6 +67,8 @@ JS_EXPORT JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef ob */ JS_EXPORT bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName); +JS_EXPORT JSObjectRef JSObjectGetProxyTarget(JSObjectRef); + #ifdef __cplusplus } #endif diff --git a/API/JSRemoteInspector.cpp b/API/JSRemoteInspector.cpp index faebc5d..3be61d0 100644 --- a/API/JSRemoteInspector.cpp +++ b/API/JSRemoteInspector.cpp @@ -50,9 +50,9 @@ void JSRemoteInspectorStart(void) #endif } -void JSRemoteInspectorSetParentProcessInformation(pid_t pid, const UInt8* auditData, size_t auditLength) +void JSRemoteInspectorSetParentProcessInformation(pid_t pid, const uint8_t* auditData, size_t auditLength) { -#if ENABLE(REMOTE_INSPECTOR) +#if ENABLE(REMOTE_INSPECTOR) && PLATFORM(COCOA) RetainPtr auditDataRef = adoptCF(CFDataCreate(kCFAllocatorDefault, auditData, auditLength)); RemoteInspector::singleton().setParentProcessInformation(pid, auditDataRef); #else diff --git a/API/JSRemoteInspector.h b/API/JSRemoteInspector.h index 2bde479..4f86510 100644 --- a/API/JSRemoteInspector.h +++ b/API/JSRemoteInspector.h @@ -29,6 +29,8 @@ #include #include +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/API/JSScriptRef.cpp b/API/JSScriptRef.cpp index 306e046..791738b 100644 --- a/API/JSScriptRef.cpp +++ b/API/JSScriptRef.cpp @@ -41,9 +41,9 @@ using namespace JSC; struct OpaqueJSScript : public SourceProvider { public: - static WTF::RefPtr create(VM* vm, const String& url, int startingLineNumber, const String& source) + static WTF::Ref create(VM& vm, const SourceOrigin& sourceOrigin, const String& url, int startingLineNumber, const String& source) { - return WTF::adoptRef(*new OpaqueJSScript(vm, url, startingLineNumber, source)); + return WTF::adoptRef(*new OpaqueJSScript(vm, sourceOrigin, url, startingLineNumber, source)); } unsigned hash() const override @@ -56,11 +56,11 @@ public: return m_source.get(); } - VM* vm() const { return m_vm; } + VM& vm() const { return m_vm; } private: - OpaqueJSScript(VM* vm, const String& url, int startingLineNumber, const String& source) - : SourceProvider(url, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()), SourceProviderSourceType::Program) + OpaqueJSScript(VM& vm, const SourceOrigin& sourceOrigin, const String& url, int startingLineNumber, const String& source) + : SourceProvider(sourceOrigin, url, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()), SourceProviderSourceType::Program) , m_vm(vm) , m_source(source.isNull() ? *StringImpl::empty() : *source.impl()) { @@ -68,14 +68,14 @@ private: virtual ~OpaqueJSScript() { } - VM* m_vm; + VM& m_vm; Ref m_source; }; -static bool parseScript(VM* vm, const SourceCode& source, ParserError& error) +static bool parseScript(VM& vm, const SourceCode& source, ParserError& error) { return !!JSC::parse( - vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, + &vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error); } @@ -84,8 +84,8 @@ extern "C" { JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, const char* source, size_t length, JSStringRef* errorMessage, int* errorLine) { - VM* vm = toJS(contextGroup); - JSLockHolder locker(vm); + auto& vm = *toJS(contextGroup); + JSLockHolder locker(&vm); for (size_t i = 0; i < length; i++) { if (!isASCII(source[i])) return 0; @@ -93,10 +93,11 @@ JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef context startingLineNumber = std::max(1, startingLineNumber); - auto result = OpaqueJSScript::create(vm, url ? url->string() : String(), startingLineNumber, String(StringImpl::createFromLiteral(source, length))); + auto sourceURLString = url ? url->string() : String(); + auto result = OpaqueJSScript::create(vm, SourceOrigin { sourceURLString }, sourceURLString, startingLineNumber, String(StringImpl::createFromLiteral(source, length))); ParserError error; - if (!parseScript(vm, SourceCode(result), error)) { + if (!parseScript(vm, SourceCode(result.copyRef()), error)) { if (errorMessage) *errorMessage = OpaqueJSString::create(error.message()).leakRef(); if (errorLine) @@ -104,20 +105,21 @@ JSScriptRef JSScriptCreateReferencingImmortalASCIIText(JSContextGroupRef context return nullptr; } - return result.leakRef(); + return &result.leakRef(); } JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef url, int startingLineNumber, JSStringRef source, JSStringRef* errorMessage, int* errorLine) { - VM* vm = toJS(contextGroup); - JSLockHolder locker(vm); + auto& vm = *toJS(contextGroup); + JSLockHolder locker(&vm); startingLineNumber = std::max(1, startingLineNumber); - auto result = OpaqueJSScript::create(vm, url ? url->string() : String(), startingLineNumber, source->string()); + auto sourceURLString = url ? url->string() : String(); + auto result = OpaqueJSScript::create(vm, SourceOrigin { sourceURLString }, sourceURLString, startingLineNumber, source->string()); ParserError error; - if (!parseScript(vm, SourceCode(result), error)) { + if (!parseScript(vm, SourceCode(result.copyRef()), error)) { if (errorMessage) *errorMessage = OpaqueJSString::create(error.message()).leakRef(); if (errorLine) @@ -125,18 +127,18 @@ JSScriptRef JSScriptCreateFromString(JSContextGroupRef contextGroup, JSStringRef return nullptr; } - return result.leakRef(); + return &result.leakRef(); } void JSScriptRetain(JSScriptRef script) { - JSLockHolder locker(script->vm()); + JSLockHolder locker(&script->vm()); script->ref(); } void JSScriptRelease(JSScriptRef script) { - JSLockHolder locker(script->vm()); + JSLockHolder locker(&script->vm()); script->deref(); } @@ -144,13 +146,13 @@ JSValueRef JSScriptEvaluate(JSContextRef context, JSScriptRef script, JSValueRef { ExecState* exec = toJS(context); JSLockHolder locker(exec); - if (script->vm() != &exec->vm()) { + if (&script->vm() != &exec->vm()) { RELEASE_ASSERT_NOT_REACHED(); return 0; } NakedPtr internalException; JSValue thisValue = thisValueRef ? toJS(exec, thisValueRef) : jsUndefined(); - JSValue result = evaluate(exec, SourceCode(script), thisValue, internalException); + JSValue result = evaluate(exec, SourceCode(*script), thisValue, internalException); if (internalException) { if (exception) *exception = toRef(exec, internalException->value()); diff --git a/API/JSStringRef.cpp b/API/JSStringRef.cpp index c9b380c..9095404 100644 --- a/API/JSStringRef.cpp +++ b/API/JSStringRef.cpp @@ -37,7 +37,7 @@ using namespace WTF::Unicode; JSStringRef JSStringCreateWithCharacters(const JSChar* chars, size_t numChars) { initializeThreading(); - return &OpaqueJSString::create(chars, numChars).leakRef(); + return &OpaqueJSString::create(reinterpret_cast(chars), numChars).leakRef(); } JSStringRef JSStringCreateWithUTF8CString(const char* string) @@ -62,7 +62,7 @@ JSStringRef JSStringCreateWithUTF8CString(const char* string) JSStringRef JSStringCreateWithCharactersNoCopy(const JSChar* chars, size_t numChars) { initializeThreading(); - return OpaqueJSString::create(StringImpl::createWithoutCopying(chars, numChars)).leakRef(); + return OpaqueJSString::create(StringImpl::createWithoutCopying(reinterpret_cast(chars), numChars)).leakRef(); } JSStringRef JSStringRetain(JSStringRef string) @@ -87,7 +87,7 @@ const JSChar* JSStringGetCharactersPtr(JSStringRef string) { if (!string) return nullptr; - return string->characters(); + return reinterpret_cast(string->characters()); } size_t JSStringGetMaximumUTF8CStringSize(JSStringRef string) diff --git a/API/JSTypedArray.cpp b/API/JSTypedArray.cpp index 14883da..5fb29e7 100644 --- a/API/JSTypedArray.cpp +++ b/API/JSTypedArray.cpp @@ -140,6 +140,7 @@ JSTypedArrayType JSValueGetTypedArrayType(JSContextRef ctx, JSValueRef valueRef, { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSValue value = toJS(exec, valueRef); @@ -147,10 +148,10 @@ JSTypedArrayType JSValueGetTypedArrayType(JSContextRef ctx, JSValueRef valueRef, return kJSTypedArrayTypeNone; JSObject* object = value.getObject(); - if (jsDynamicCast(object)) + if (jsDynamicCast(vm, object)) return kJSTypedArrayTypeArrayBuffer; - return toJSTypedArrayType(object->classInfo()->typedArrayStorageType); + return toJSTypedArrayType(object->classInfo(vm)->typedArrayStorageType); } JSObjectRef JSObjectMakeTypedArray(JSContextRef ctx, JSTypedArrayType arrayType, size_t length, JSValueRef* exception) @@ -193,12 +194,13 @@ JSObjectRef JSObjectMakeTypedArrayWithBytesNoCopy(JSContextRef ctx, JSTypedArray JSObjectRef JSObjectMakeTypedArrayWithArrayBuffer(JSContextRef ctx, JSTypedArrayType arrayType, JSObjectRef jsBufferRef, JSValueRef* exception) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); if (arrayType == kJSTypedArrayTypeNone || arrayType == kJSTypedArrayTypeArrayBuffer) return nullptr; - JSArrayBuffer* jsBuffer = jsDynamicCast(toJS(jsBufferRef)); + JSArrayBuffer* jsBuffer = jsDynamicCast(vm, toJS(jsBufferRef)); if (!jsBuffer) { setException(exec, exception, createTypeError(exec, "JSObjectMakeTypedArrayWithArrayBuffer expects buffer to be an Array Buffer object")); return nullptr; @@ -216,12 +218,13 @@ JSObjectRef JSObjectMakeTypedArrayWithArrayBuffer(JSContextRef ctx, JSTypedArray JSObjectRef JSObjectMakeTypedArrayWithArrayBufferAndOffset(JSContextRef ctx, JSTypedArrayType arrayType, JSObjectRef jsBufferRef, size_t offset, size_t length, JSValueRef* exception) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); if (arrayType == kJSTypedArrayTypeNone || arrayType == kJSTypedArrayTypeArrayBuffer) return nullptr; - JSArrayBuffer* jsBuffer = jsDynamicCast(toJS(jsBufferRef)); + JSArrayBuffer* jsBuffer = jsDynamicCast(vm, toJS(jsBufferRef)); if (!jsBuffer) { setException(exec, exception, createTypeError(exec, "JSObjectMakeTypedArrayWithArrayBuffer expects buffer to be an Array Buffer object")); return nullptr; @@ -236,10 +239,11 @@ JSObjectRef JSObjectMakeTypedArrayWithArrayBufferAndOffset(JSContextRef ctx, JST void* JSObjectGetTypedArrayBytesPtr(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* object = toJS(objectRef); - if (JSArrayBufferView* typedArray = jsDynamicCast(object)) { + if (JSArrayBufferView* typedArray = jsDynamicCast(vm, object)) { ArrayBuffer* buffer = typedArray->possiblySharedBuffer(); buffer->pinAndLock(); return buffer->data(); @@ -247,31 +251,37 @@ void* JSObjectGetTypedArrayBytesPtr(JSContextRef ctx, JSObjectRef objectRef, JSV return nullptr; } -size_t JSObjectGetTypedArrayLength(JSContextRef, JSObjectRef objectRef, JSValueRef*) +size_t JSObjectGetTypedArrayLength(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) { + ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSObject* object = toJS(objectRef); - if (JSArrayBufferView* typedArray = jsDynamicCast(object)) + if (JSArrayBufferView* typedArray = jsDynamicCast(vm, object)) return typedArray->length(); return 0; } -size_t JSObjectGetTypedArrayByteLength(JSContextRef, JSObjectRef objectRef, JSValueRef*) +size_t JSObjectGetTypedArrayByteLength(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) { + ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSObject* object = toJS(objectRef); - if (JSArrayBufferView* typedArray = jsDynamicCast(object)) - return typedArray->length() * elementSize(typedArray->classInfo()->typedArrayStorageType); + if (JSArrayBufferView* typedArray = jsDynamicCast(vm, object)) + return typedArray->length() * elementSize(typedArray->classInfo(vm)->typedArrayStorageType); return 0; } -size_t JSObjectGetTypedArrayByteOffset(JSContextRef, JSObjectRef objectRef, JSValueRef*) +size_t JSObjectGetTypedArrayByteOffset(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) { + ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSObject* object = toJS(objectRef); - if (JSArrayBufferView* typedArray = jsDynamicCast(object)) + if (JSArrayBufferView* typedArray = jsDynamicCast(vm, object)) return typedArray->byteOffset(); return 0; @@ -280,10 +290,11 @@ size_t JSObjectGetTypedArrayByteOffset(JSContextRef, JSObjectRef objectRef, JSVa JSObjectRef JSObjectGetTypedArrayBuffer(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* object = toJS(objectRef); - if (JSArrayBufferView* typedArray = jsDynamicCast(object)) + if (JSArrayBufferView* typedArray = jsDynamicCast(vm, object)) return toRef(exec->vm().m_typedArrayController->toJS(exec, typedArray->globalObject(), typedArray->possiblySharedBuffer())); return nullptr; @@ -306,25 +317,33 @@ JSObjectRef JSObjectMakeArrayBufferWithBytesNoCopy(JSContextRef ctx, void* bytes return toRef(jsBuffer); } -void* JSObjectGetArrayBufferBytesPtr(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) +void* JSObjectGetArrayBufferBytesPtr(JSContextRef ctx, JSObjectRef objectRef, JSValueRef* exception) { ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSObject* object = toJS(objectRef); - if (JSArrayBuffer* jsBuffer = jsDynamicCast(object)) { + if (JSArrayBuffer* jsBuffer = jsDynamicCast(vm, object)) { ArrayBuffer* buffer = jsBuffer->impl(); + if (buffer->isWasmMemory()) { + setException(exec, exception, createTypeError(exec, ASCIILiteral("Cannot get the backing buffer for a WebAssembly.Memory"))); + return nullptr; + } + buffer->pinAndLock(); return buffer->data(); } return nullptr; } -size_t JSObjectGetArrayBufferByteLength(JSContextRef, JSObjectRef objectRef, JSValueRef*) +size_t JSObjectGetArrayBufferByteLength(JSContextRef ctx, JSObjectRef objectRef, JSValueRef*) { + ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSObject* object = toJS(objectRef); - if (JSArrayBuffer* jsBuffer = jsDynamicCast(object)) + if (JSArrayBuffer* jsBuffer = jsDynamicCast(vm, object)) return jsBuffer->impl()->byteLength(); return 0; diff --git a/API/JSValue.mm b/API/JSValue.mm index bab2862..6986fae 100644 --- a/API/JSValue.mm +++ b/API/JSValue.mm @@ -571,16 +571,16 @@ NSString * const JSPropertyDescriptorSetKey = @"set"; @end -inline bool isDate(JSObjectRef object, JSGlobalContextRef context) +inline bool isDate(JSC::VM& vm, JSObjectRef object, JSGlobalContextRef context) { JSC::JSLockHolder locker(toJS(context)); - return toJS(object)->inherits(JSC::DateInstance::info()); + return toJS(object)->inherits(vm, JSC::DateInstance::info()); } -inline bool isArray(JSObjectRef object, JSGlobalContextRef context) +inline bool isArray(JSC::VM& vm, JSObjectRef object, JSGlobalContextRef context) { JSC::JSLockHolder locker(toJS(context)); - return toJS(object)->inherits(JSC::JSArray::info()); + return toJS(object)->inherits(vm, JSC::JSArray::info()); } @implementation JSValue(Internal) @@ -656,6 +656,9 @@ static void reportExceptionToInspector(JSGlobalContextRef context, JSC::JSValue static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef context, JSValueRef value) { + JSC::ExecState* exec = toJS(context); + JSC::VM& vm = exec->vm(); + if (!JSValueIsObject(context, value)) { id primitive; if (JSValueIsBoolean(context, value)) @@ -685,10 +688,10 @@ static JSContainerConvertor::Task valueToObjectWithoutCopy(JSGlobalContextRef co if (id wrapped = tryUnwrapObjcObject(context, object)) return (JSContainerConvertor::Task){ object, wrapped, ContainerNone }; - if (isDate(object, context)) + if (isDate(vm, object, context)) return (JSContainerConvertor::Task){ object, [NSDate dateWithTimeIntervalSince1970:JSValueToNumber(context, object, 0) / 1000.0], ContainerNone }; - if (isArray(object, context)) + if (isArray(vm, object, context)) return (JSContainerConvertor::Task){ object, [NSMutableArray array], ContainerArray }; return (JSContainerConvertor::Task){ object, [NSMutableDictionary dictionary], ContainerDictionary }; diff --git a/API/JSValueRef.cpp b/API/JSValueRef.cpp index c27b7c3..64ac6c3 100644 --- a/API/JSValueRef.cpp +++ b/API/JSValueRef.cpp @@ -169,9 +169,10 @@ bool JSValueIsArray(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); - return toJS(exec, value).inherits(JSArray::info()); + return toJS(exec, value).inherits(vm, JSArray::info()); } bool JSValueIsDate(JSContextRef ctx, JSValueRef value) @@ -181,9 +182,10 @@ bool JSValueIsDate(JSContextRef ctx, JSValueRef value) return false; } ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); - return toJS(exec, value).inherits(DateInstance::info()); + return toJS(exec, value).inherits(vm, DateInstance::info()); } bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass) @@ -193,20 +195,21 @@ bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsCla return false; } ExecState* exec = toJS(ctx); + VM& vm = exec->vm(); JSLockHolder locker(exec); JSValue jsValue = toJS(exec, value); if (JSObject* o = jsValue.getObject()) { - if (o->inherits(JSProxy::info())) + if (o->inherits(vm, JSProxy::info())) o = jsCast(o)->target(); - if (o->inherits(JSCallbackObject::info())) + if (o->inherits(vm, JSCallbackObject::info())) return jsCast*>(o)->inherits(jsClass); - if (o->inherits(JSCallbackObject::info())) + if (o->inherits(vm, JSCallbackObject::info())) return jsCast*>(o)->inherits(jsClass); #if JSC_OBJC_API_ENABLED - if (o->inherits(JSCallbackObject::info())) + if (o->inherits(vm, JSCallbackObject::info())) return jsCast*>(o)->inherits(jsClass); #endif } diff --git a/API/JSVirtualMachine.mm b/API/JSVirtualMachine.mm index 2bbc043..5145ad9 100644 --- a/API/JSVirtualMachine.mm +++ b/API/JSVirtualMachine.mm @@ -226,11 +226,6 @@ static id getInternalObjcObject(id object) } } -- (void)enableSigillCrashAnalyzer -{ - JSC::enableSigillCrashAnalyzer(); -} - @end @implementation JSVirtualMachine(Internal) diff --git a/API/JSWeakObjectMapRefPrivate.cpp b/API/JSWeakObjectMapRefPrivate.cpp index 9b825b0..28cf244 100644 --- a/API/JSWeakObjectMapRefPrivate.cpp +++ b/API/JSWeakObjectMapRefPrivate.cpp @@ -61,9 +61,9 @@ void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSO JSObject* obj = toJS(object); if (!obj) return; - ASSERT(obj->inherits(JSProxy::info()) - || obj->inherits(JSCallbackObject::info()) - || obj->inherits(JSCallbackObject::info())); + ASSERT(obj->inherits(exec->vm(), JSProxy::info()) + || obj->inherits(exec->vm(), JSCallbackObject::info()) + || obj->inherits(exec->vm(), JSCallbackObject::info())); map->map().set(key, obj); } diff --git a/API/JSWeakPrivate.cpp b/API/JSWeakPrivate.cpp new file mode 100644 index 0000000..246649f --- /dev/null +++ b/API/JSWeakPrivate.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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 "JSWeakPrivate.h" + +#include "APICast.h" +#include "JSCInlines.h" +#include "Weak.h" +#include + +using namespace JSC; + +struct OpaqueJSWeak : ThreadSafeRefCounted { + OpaqueJSWeak(JSObject* object) + : weak(object) + { + } + + Weak weak; +}; + +JSWeakRef JSWeakCreate(JSContextGroupRef contextGroup, JSObjectRef objectRef) +{ + VM* vm = toJS(contextGroup); + JSLockHolder locker(vm); + return new OpaqueJSWeak(toJS(objectRef)); +} + +void JSWeakRetain(JSContextGroupRef contextGroup, JSWeakRef weakRef) +{ + VM* vm = toJS(contextGroup); + JSLockHolder locker(vm); + weakRef->ref(); +} + +void JSWeakRelease(JSContextGroupRef contextGroup, JSWeakRef weakRef) +{ + VM* vm = toJS(contextGroup); + JSLockHolder locker(vm); + weakRef->deref(); +} + +JSObjectRef JSWeakGetObject(JSWeakRef weakRef) +{ + return toRef(weakRef->weak.get()); +} + diff --git a/API/JSWeakPrivate.h b/API/JSWeakPrivate.h new file mode 100644 index 0000000..9ca2ffa --- /dev/null +++ b/API/JSWeakPrivate.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. + */ + +#ifndef JSWeakPrivate_h +#define JSWeakPrivate_h + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef const struct OpaqueJSWeak* JSWeakRef; + +JS_EXPORT JSWeakRef JSWeakCreate(JSContextGroupRef, JSObjectRef); + +JS_EXPORT void JSWeakRetain(JSContextGroupRef, JSWeakRef); +JS_EXPORT void JSWeakRelease(JSContextGroupRef, JSWeakRef); + +JS_EXPORT JSObjectRef JSWeakGetObject(JSWeakRef); + +#ifdef __cplusplus +} +#endif + +#endif // JSWeakPrivate_h + diff --git a/API/JSWrapperMap.h b/API/JSWrapperMap.h index c6aa1af..6c18c64 100644 --- a/API/JSWrapperMap.h +++ b/API/JSWrapperMap.h @@ -31,11 +31,11 @@ @interface JSWrapperMap : NSObject -- (id)initWithContext:(JSContext *)context; +- (instancetype)initWithGlobalContextRef:(JSGlobalContextRef)context; -- (JSValue *)jsWrapperForObject:(id)object; +- (JSValue *)jsWrapperForObject:(id)object inContext:(JSContext *)context; -- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value; +- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value inContext:(JSContext *)context; @end diff --git a/API/JSWrapperMap.mm b/API/JSWrapperMap.mm index 8046188..8cce369 100644 --- a/API/JSWrapperMap.mm +++ b/API/JSWrapperMap.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2013-2015, 2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,6 +35,7 @@ #import "JSWrapperMap.h" #import "ObjCCallbackFunction.h" #import "ObjcRuntimeExtras.h" +#import "ObjectConstructor.h" #import "WeakGCMap.h" #import "WeakGCMapInlines.h" #import @@ -363,7 +364,6 @@ static void copyPrototypeProperties(JSContext *context, Class objcClass, Protoco } @interface JSObjCClassInfo : NSObject { - JSContext *m_context; Class m_class; bool m_block; JSClassRef m_classRef; @@ -371,23 +371,22 @@ static void copyPrototypeProperties(JSContext *context, Class objcClass, Protoco JSC::Weak m_constructor; } -- (id)initWithContext:(JSContext *)context forClass:(Class)cls; -- (JSC::JSObject *)wrapperForObject:(id)object; -- (JSC::JSObject *)constructor; -- (JSC::JSObject *)prototype; +- (instancetype)initForClass:(Class)cls; +- (JSC::JSObject *)wrapperForObject:(id)object inContext:(JSContext *)context; +- (JSC::JSObject *)constructorInContext:(JSContext *)context; +- (JSC::JSObject *)prototypeInContext:(JSContext *)context; @end @implementation JSObjCClassInfo -- (id)initWithContext:(JSContext *)context forClass:(Class)cls +- (instancetype)initForClass:(Class)cls { self = [super init]; if (!self) return nil; const char* className = class_getName(cls); - m_context = context; m_class = cls; m_block = [cls isSubclassOfClass:getNSBlockClass()]; JSClassDefinition definition; @@ -413,7 +412,7 @@ static JSC::JSObject* allocateConstructorForCustomClass(JSContext *context, cons __block HashMap initTable; Protocol *exportProtocol = getJSExportProtocol(); for (Class currentClass = cls; currentClass; currentClass = class_getSuperclass(currentClass)) { - forEachProtocolImplementingProtocol(currentClass, exportProtocol, ^(Protocol *protocol) { + forEachProtocolImplementingProtocol(currentClass, exportProtocol, ^(Protocol *protocol, bool&) { forEachMethodInProtocol(protocol, YES, YES, ^(SEL selector, const char*) { const char* name = sel_getName(selector); if (!isInitFamilyMethod(@(name))) @@ -458,9 +457,9 @@ static JSC::JSObject* allocateConstructorForCustomClass(JSContext *context, cons typedef std::pair ConstructorPrototypePair; -- (ConstructorPrototypePair)allocateConstructorAndPrototype +- (ConstructorPrototypePair)allocateConstructorAndPrototypeInContext:(JSContext *)context { - JSObjCClassInfo* superClassInfo = [m_context.wrapperMap classInfoForClass:class_getSuperclass(m_class)]; + JSObjCClassInfo* superClassInfo = [context.wrapperMap classInfoForClass:class_getSuperclass(m_class)]; ASSERT(!m_constructor || !m_prototype); ASSERT((m_class == [NSObject class]) == !superClassInfo); @@ -469,39 +468,36 @@ typedef std::pair ConstructorPrototypePair; JSC::JSObject* jsConstructor = m_constructor.get(); if (!superClassInfo) { - JSContextRef cContext = [m_context JSGlobalContextRef]; - JSValue *constructor = m_context[@"Object"]; + JSC::JSGlobalObject* globalObject = toJSGlobalObject([context JSGlobalContextRef]); if (!jsConstructor) - jsConstructor = toJS(JSValueToObject(cContext, valueInternalValue(constructor), 0)); + jsConstructor = globalObject->objectConstructor(); - if (!jsPrototype) { - JSValue *prototype = constructor[@"prototype"]; - jsPrototype = toJS(JSValueToObject(cContext, valueInternalValue(prototype), 0)); - } + if (!jsPrototype) + jsPrototype = globalObject->objectPrototype(); } else { const char* className = class_getName(m_class); // Create or grab the prototype/constructor pair. if (!jsPrototype) - jsPrototype = objectWithCustomBrand(m_context, [NSString stringWithFormat:@"%sPrototype", className]); + jsPrototype = objectWithCustomBrand(context, [NSString stringWithFormat:@"%sPrototype", className]); if (!jsConstructor) - jsConstructor = allocateConstructorForCustomClass(m_context, className, m_class); + jsConstructor = allocateConstructorForCustomClass(context, className, m_class); - JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:m_context]; - JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:m_context]; + JSValue* prototype = [JSValue valueWithJSValueRef:toRef(jsPrototype) inContext:context]; + JSValue* constructor = [JSValue valueWithJSValueRef:toRef(jsConstructor) inContext:context]; putNonEnumerable(prototype, @"constructor", constructor); putNonEnumerable(constructor, @"prototype", prototype); Protocol *exportProtocol = getJSExportProtocol(); - forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol){ - copyPrototypeProperties(m_context, m_class, protocol, prototype); - copyMethodsToObject(m_context, m_class, protocol, NO, constructor); + forEachProtocolImplementingProtocol(m_class, exportProtocol, ^(Protocol *protocol, bool&){ + copyPrototypeProperties(context, m_class, protocol, prototype); + copyMethodsToObject(context, m_class, protocol, NO, constructor); }); // Set [Prototype]. - JSC::JSObject* superClassPrototype = [superClassInfo prototype]; - JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(jsPrototype), toRef(superClassPrototype)); + JSC::JSObject* superClassPrototype = [superClassInfo prototypeInContext:context]; + JSObjectSetPrototype([context JSGlobalContextRef], toRef(jsPrototype), toRef(superClassPrototype)); } m_prototype = jsPrototype; @@ -509,41 +505,41 @@ typedef std::pair ConstructorPrototypePair; return ConstructorPrototypePair(jsConstructor, jsPrototype); } -- (JSC::JSObject*)wrapperForObject:(id)object +- (JSC::JSObject*)wrapperForObject:(id)object inContext:(JSContext *)context { ASSERT([object isKindOfClass:m_class]); ASSERT(m_block == [object isKindOfClass:getNSBlockClass()]); if (m_block) { - if (JSObjectRef method = objCCallbackFunctionForBlock(m_context, object)) { - JSValue *constructor = [JSValue valueWithJSValueRef:method inContext:m_context]; - JSValue *prototype = [JSValue valueWithNewObjectInContext:m_context]; + if (JSObjectRef method = objCCallbackFunctionForBlock(context, object)) { + JSValue *constructor = [JSValue valueWithJSValueRef:method inContext:context]; + JSValue *prototype = [JSValue valueWithNewObjectInContext:context]; putNonEnumerable(constructor, @"prototype", prototype); putNonEnumerable(prototype, @"constructor", constructor); return toJS(method); } } - JSC::JSObject* prototype = [self prototype]; + JSC::JSObject* prototype = [self prototypeInContext:context]; - JSC::JSObject* wrapper = makeWrapper([m_context JSGlobalContextRef], m_classRef, object); - JSObjectSetPrototype([m_context JSGlobalContextRef], toRef(wrapper), toRef(prototype)); + JSC::JSObject* wrapper = makeWrapper([context JSGlobalContextRef], m_classRef, object); + JSObjectSetPrototype([context JSGlobalContextRef], toRef(wrapper), toRef(prototype)); return wrapper; } -- (JSC::JSObject*)constructor +- (JSC::JSObject*)constructorInContext:(JSContext *)context { JSC::JSObject* constructor = m_constructor.get(); if (!constructor) - constructor = [self allocateConstructorAndPrototype].first; + constructor = [self allocateConstructorAndPrototypeInContext:context].first; ASSERT(!!constructor); return constructor; } -- (JSC::JSObject*)prototype +- (JSC::JSObject*)prototypeInContext:(JSContext *)context { JSC::JSObject* prototype = m_prototype.get(); if (!prototype) - prototype = [self allocateConstructorAndPrototype].second; + prototype = [self allocateConstructorAndPrototypeInContext:context].second; ASSERT(!!prototype); return prototype; } @@ -551,13 +547,12 @@ typedef std::pair ConstructorPrototypePair; @end @implementation JSWrapperMap { - JSContext *m_context; NSMutableDictionary *m_classMap; std::unique_ptr> m_cachedJSWrappers; NSMapTable *m_cachedObjCWrappers; } -- (id)initWithContext:(JSContext *)context +- (instancetype)initWithGlobalContextRef:(JSGlobalContextRef)context { self = [super init]; if (!self) @@ -567,9 +562,10 @@ typedef std::pair ConstructorPrototypePair; NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality; m_cachedObjCWrappers = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; - m_cachedJSWrappers = std::make_unique>(toJS([context JSGlobalContextRef])->vm()); + m_cachedJSWrappers = std::make_unique>(toJS(context)->vm()); - m_context = context; + ASSERT(!toJSGlobalObject(context)->wrapperMap()); + toJSGlobalObject(context)->setWrapperMap(self); m_classMap = [[NSMutableDictionary alloc] init]; return self; } @@ -591,23 +587,32 @@ typedef std::pair ConstructorPrototypePair; return classInfo; // Skip internal classes beginning with '_' - just copy link to the parent class's info. - if ('_' == *class_getName(cls)) - return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)]; + if ('_' == *class_getName(cls)) { + bool conformsToExportProtocol = false; + forEachProtocolImplementingProtocol(cls, getJSExportProtocol(), [&conformsToExportProtocol](Protocol *, bool& stop) { + conformsToExportProtocol = true; + stop = true; + }); - return m_classMap[cls] = [[[JSObjCClassInfo alloc] initWithContext:m_context forClass:cls] autorelease]; + if (!conformsToExportProtocol) + return m_classMap[cls] = [self classInfoForClass:class_getSuperclass(cls)]; + } + + return m_classMap[cls] = [[[JSObjCClassInfo alloc] initForClass:cls] autorelease]; } -- (JSValue *)jsWrapperForObject:(id)object +- (JSValue *)jsWrapperForObject:(id)object inContext:(JSContext *)context { + ASSERT(toJSGlobalObject([context JSGlobalContextRef])->wrapperMap() == self); JSC::JSObject* jsWrapper = m_cachedJSWrappers->get(object); if (jsWrapper) - return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context]; + return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:context]; if (class_isMetaClass(object_getClass(object))) - jsWrapper = [[self classInfoForClass:(Class)object] constructor]; + jsWrapper = [[self classInfoForClass:(Class)object] constructorInContext:context]; else { JSObjCClassInfo* classInfo = [self classInfoForClass:[object class]]; - jsWrapper = [classInfo wrapperForObject:object]; + jsWrapper = [classInfo wrapperForObject:object inContext:context]; } // FIXME: https://bugs.webkit.org/show_bug.cgi?id=105891 @@ -616,14 +621,15 @@ typedef std::pair ConstructorPrototypePair; // (2) A long lived object may rack up many JSValues. When the contexts are released these will unprotect the associated JavaScript objects, // but still, would probably nicer if we made it so that only one associated object was required, broadcasting object dealloc. m_cachedJSWrappers->set(object, jsWrapper); - return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:m_context]; + return [JSValue valueWithJSValueRef:toRef(jsWrapper) inContext:context]; } -- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value +- (JSValue *)objcWrapperForJSValueRef:(JSValueRef)value inContext:context { + ASSERT(toJSGlobalObject([context JSGlobalContextRef])->wrapperMap() == self); JSValue *wrapper = static_cast(NSMapGet(m_cachedObjCWrappers, value)); if (!wrapper) { - wrapper = [[[JSValue alloc] initWithValue:value inContext:m_context] autorelease]; + wrapper = [[[JSValue alloc] initWithValue:value inContext:context] autorelease]; NSMapInsert(m_cachedObjCWrappers, value, wrapper); } return wrapper; @@ -639,9 +645,10 @@ id tryUnwrapObjcObject(JSGlobalContextRef context, JSValueRef value) JSObjectRef object = JSValueToObject(context, value, &exception); ASSERT(!exception); JSC::JSLockHolder locker(toJS(context)); - if (toJS(object)->inherits(JSC::JSCallbackObject::info())) + JSC::VM& vm = toJS(context)->vm(); + if (toJS(object)->inherits(vm, JSC::JSCallbackObject::info())) return (id)JSC::jsCast(toJS(object))->wrappedObject(); - if (id target = tryUnwrapConstructor(object)) + if (id target = tryUnwrapConstructor(&vm, object)) return target; return nil; } diff --git a/API/ObjCCallbackFunction.h b/API/ObjCCallbackFunction.h index 1c0995e..4d5b736 100644 --- a/API/ObjCCallbackFunction.h +++ b/API/ObjCCallbackFunction.h @@ -36,7 +36,7 @@ JSObjectRef objCCallbackFunctionForMethod(JSContext *, Class, Protocol *, BOOL i JSObjectRef objCCallbackFunctionForBlock(JSContext *, id); JSObjectRef objCCallbackFunctionForInit(JSContext *, Class, Protocol *, SEL, const char* types); -id tryUnwrapConstructor(JSObjectRef); +id tryUnwrapConstructor(JSC::VM*, JSObjectRef); #endif namespace JSC { diff --git a/API/ObjCCallbackFunction.mm b/API/ObjCCallbackFunction.mm index ffdc0d4..b014783 100644 --- a/API/ObjCCallbackFunction.mm +++ b/API/ObjCCallbackFunction.mm @@ -503,7 +503,7 @@ static JSObjectRef objCCallbackFunctionCallAsConstructor(JSContextRef callerCont return (JSObjectRef)result; } -const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, 0, CREATE_METHOD_TABLE(ObjCCallbackFunction) }; +const JSC::ClassInfo ObjCCallbackFunction::s_info = { "CallbackFunction", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ObjCCallbackFunction) }; ObjCCallbackFunction::ObjCCallbackFunction(JSC::VM& vm, JSC::Structure* structure, JSObjectCallAsFunctionCallback functionCallback, JSObjectCallAsConstructorCallback constructCallback, std::unique_ptr impl) : Base(vm, structure) @@ -523,7 +523,7 @@ ObjCCallbackFunction* ObjCCallbackFunction::create(JSC::VM& vm, JSC::JSGlobalObj void ObjCCallbackFunction::destroy(JSCell* cell) { - ObjCCallbackFunction& function = *jsCast(cell); + ObjCCallbackFunction& function = *static_cast(cell); function.impl()->destroy(*Heap::heap(cell)); function.~ObjCCallbackFunction(); } @@ -715,9 +715,9 @@ JSObjectRef objCCallbackFunctionForBlock(JSContext *context, id target) return objCCallbackFunctionForInvocation(context, invocation, CallbackBlock, nil, signature); } -id tryUnwrapConstructor(JSObjectRef object) +id tryUnwrapConstructor(JSC::VM* vm, JSObjectRef object) { - if (!toJS(object)->inherits(JSC::ObjCCallbackFunction::info())) + if (!toJS(object)->inherits(*vm, JSC::ObjCCallbackFunction::info())) return nil; JSC::ObjCCallbackFunctionImpl* impl = static_cast(toJS(object))->impl(); if (!impl->isConstructible()) diff --git a/API/ObjcRuntimeExtras.h b/API/ObjcRuntimeExtras.h index 128df5c..fa44ff6 100644 --- a/API/ObjcRuntimeExtras.h +++ b/API/ObjcRuntimeExtras.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013, 2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -42,7 +42,7 @@ inline bool protocolImplementsProtocol(Protocol *candidate, Protocol *target) return false; } -inline void forEachProtocolImplementingProtocol(Class cls, Protocol *target, void (^callback)(Protocol *)) +inline void forEachProtocolImplementingProtocol(Class cls, Protocol *target, void (^callback)(Protocol *, bool& stop)) { ASSERT(cls); ASSERT(target); @@ -56,6 +56,7 @@ inline void forEachProtocolImplementingProtocol(Class cls, Protocol *target, voi worklist.append(protocols, protocolsCount); free(protocols); + bool stop = false; while (!worklist.isEmpty()) { Protocol *protocol = worklist.last(); worklist.removeLast(); @@ -65,8 +66,11 @@ inline void forEachProtocolImplementingProtocol(Class cls, Protocol *target, voi continue; // If it implements the protocol, make the callback. - if (protocolImplementsProtocol(protocol, target)) - callback(protocol); + if (protocolImplementsProtocol(protocol, target)) { + callback(protocol, stop); + if (stop) + break; + } // Add incorporated protocols to the worklist. protocols = protocol_copyProtocolList(protocol, &protocolsCount); diff --git a/API/WebKitAvailability.h b/API/WebKitAvailability.h index ab53183..8227520 100644 --- a/API/WebKitAvailability.h +++ b/API/WebKitAvailability.h @@ -66,7 +66,7 @@ #define AVAILABLE_MAC_OS_X_VERSION_10_10_AND_LATER #endif -#endif /* __MAC_OS_X_VERSION_MIN_REQUIRED <= 101100 */ +#endif /* !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100 */ #if defined(BUILDING_GTK__) #undef CF_AVAILABLE diff --git a/API/tests/CompareAndSwapTest.cpp b/API/tests/CompareAndSwapTest.cpp index e78086c..7c5b128 100644 --- a/API/tests/CompareAndSwapTest.cpp +++ b/API/tests/CompareAndSwapTest.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "CompareAndSwapTest.h" +#include #include #include #include @@ -96,7 +97,7 @@ void testCompareAndSwap() { Bitmap bitmap; const int numThreads = 5; - ThreadIdentifier threadIDs[numThreads]; + RefPtr threads[numThreads]; Data data[numThreads]; WTF::initializeThreading(); @@ -106,13 +107,12 @@ void testCompareAndSwap() data[i].bitmap = &bitmap; data[i].id = i; data[i].numThreads = numThreads; - std::function threadFunc = std::bind(setBitThreadFunc, &data[i]); - threadIDs[i] = createThread("setBitThreadFunc", threadFunc); + threads[i] = Thread::create("setBitThreadFunc", std::bind(setBitThreadFunc, &data[i])); } printf("Waiting for %d threads to join\n", numThreads); for (int i = 0; i < numThreads; i++) - waitForThreadCompletion(threadIDs[i]); + threads[i]->waitForCompletion(); printf("PASS: CompareAndSwap test completed without a hang\n"); } diff --git a/API/tests/CurrentThisInsideBlockGetterTest.h b/API/tests/CurrentThisInsideBlockGetterTest.h index ab68f80..498e15f 100644 --- a/API/tests/CurrentThisInsideBlockGetterTest.h +++ b/API/tests/CurrentThisInsideBlockGetterTest.h @@ -25,7 +25,7 @@ #pragma once -#include +#include #if JSC_OBJC_API_ENABLED diff --git a/API/tests/CustomGlobalObjectClassTest.c b/API/tests/CustomGlobalObjectClassTest.c index 62e6397..976a881 100644 --- a/API/tests/CustomGlobalObjectClassTest.c +++ b/API/tests/CustomGlobalObjectClassTest.c @@ -26,8 +26,10 @@ #include "CustomGlobalObjectClassTest.h" #include -#include +#include #include +#include +#include extern bool assertTrue(bool value, const char* message); diff --git a/API/tests/DateTests.mm b/API/tests/DateTests.mm index e2837a6..2bda3ad 100644 --- a/API/tests/DateTests.mm +++ b/API/tests/DateTests.mm @@ -67,6 +67,7 @@ static unsigned unitFlags = NSCalendarUnitSecond | NSCalendarUnitMinute | NSCale JSContext *context = [[JSContext alloc] init]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"MMMM dd',' yyyy hh:mm:ss"]; + [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]]; NSDate *februaryFourth2014 = [formatter dateFromString:@"February 4, 2014 11:40:03"]; NSDateComponents *components = [[NSCalendar currentCalendar] components:unitFlags fromDate:februaryFourth2014]; // Months are 0-indexed for JavaScript Dates. @@ -93,6 +94,7 @@ static unsigned unitFlags = NSCalendarUnitSecond | NSCalendarUnitMinute | NSCale [context evaluateScript:@"function jsReturnDate(date) { return date; }"]; NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"MMMM dd',' yyyy hh:mm:ss"]; + [formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]]; NSDate *februaryFourth2014 = [formatter dateFromString:@"February 4, 2014 11:40:03"]; NSDateComponents *components = [[NSCalendar currentCalendar] components:unitFlags fromDate:februaryFourth2014]; diff --git a/API/tests/ExecutionTimeLimitTest.cpp b/API/tests/ExecutionTimeLimitTest.cpp index d5e5324..73f324d 100644 --- a/API/tests/ExecutionTimeLimitTest.cpp +++ b/API/tests/ExecutionTimeLimitTest.cpp @@ -28,12 +28,20 @@ #include "InitializeThreading.h" #include "JSContextRefPrivate.h" -#include "JavaScriptCore.h" +#include "JavaScript.h" #include "Options.h" + #include +#include +#include #include +#include #include +#if HAVE(MACH_EXCEPTIONS) +#include +#endif + using namespace std::chrono; using JSC::Options; @@ -77,6 +85,15 @@ static bool extendTerminateCallback(JSContextRef ctx, void*) return true; } +#if HAVE(MACH_EXCEPTIONS) +bool dispatchTerminateCallbackCalled = false; +static bool dispatchTermitateCallback(JSContextRef, void*) +{ + dispatchTerminateCallbackCalled = true; + return true; +} +#endif + struct TierOptions { const char* tier; unsigned timeLimitAdjustmentMillis; @@ -104,8 +121,8 @@ int testExecutionTimeLimit() static const TierOptions tierOptionsList[] = { { "LLINT", 0, "--useConcurrentJIT=false --useLLInt=true --useJIT=false" }, { "Baseline", 0, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=false" }, - { "DFG", 0, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=true --useFTLJIT=false" }, - { "FTL", 200, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=true --useFTLJIT=true" }, + { "DFG", 200, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=true --useFTLJIT=false" }, + { "FTL", 500, "--useConcurrentJIT=false --useLLInt=true --useJIT=true --useDFGJIT=true --useFTLJIT=true" }, }; bool failed = false; @@ -134,7 +151,39 @@ int testExecutionTimeLimit() JSObjectRef currentCPUTimeFunction = JSObjectMakeFunctionWithCallback(context, currentCPUTimeStr, currentCPUTimeAsJSFunctionCallback); JSObjectSetProperty(context, globalObject, currentCPUTimeStr, currentCPUTimeFunction, kJSPropertyAttributeNone, nullptr); JSStringRelease(currentCPUTimeStr); - + + /* Test script on another thread: */ + timeLimit = (100 + tierAdjustmentMillis) / 1000.0; + JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, shouldTerminateCallback, 0); + { + unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis; + + JSStringRef script = JSStringCreateWithUTF8CString("function foo() { while (true) { } } foo();"); + exception = nullptr; + JSValueRef* exn = &exception; + shouldTerminateCallbackWasCalled = false; + auto thread = Thread::create("Rogue thread", [=] { + JSEvaluateScript(context, script, nullptr, nullptr, 1, exn); + }); + + sleep(Seconds(timeAfterWatchdogShouldHaveFired / 1000.0)); + + if (shouldTerminateCallbackWasCalled) + printf("PASS: %s script timed out as expected.\n", tierOptions.tier); + else { + printf("FAIL: %s script timeout callback was not called.\n", tierOptions.tier); + exit(1); + } + + if (!exception) { + printf("FAIL: %s TerminatedExecutionException was not thrown.\n", tierOptions.tier); + exit(1); + } + + thread->waitForCompletion(); + testResetAfterTimeout(failed); + } + /* Test script timeout: */ timeLimit = (100 + tierAdjustmentMillis) / 1000.0; JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, shouldTerminateCallback, 0); @@ -365,6 +414,65 @@ int testExecutionTimeLimit() } } +#if HAVE(MACH_EXCEPTIONS) + /* Test script timeout from dispatch queue: */ + timeLimit = (100 + tierAdjustmentMillis) / 1000.0; + JSContextGroupSetExecutionTimeLimit(contextGroup, timeLimit, dispatchTermitateCallback, 0); + { + unsigned timeAfterWatchdogShouldHaveFired = 300 + tierAdjustmentMillis; + + StringBuilder scriptBuilder; + scriptBuilder.appendLiteral("function foo() { var startTime = currentCPUTime(); while (true) { for (var i = 0; i < 1000; i++); if (currentCPUTime() - startTime > "); + scriptBuilder.appendNumber(timeAfterWatchdogShouldHaveFired / 1000.0); + scriptBuilder.appendLiteral(") break; } } foo();"); + + JSStringRef script = JSStringCreateWithUTF8CString(scriptBuilder.toString().utf8().data()); + exception = nullptr; + dispatchTerminateCallbackCalled = false; + + // We have to do this since blocks can only capture things as const. + JSGlobalContextRef& contextRef = context; + JSStringRef& scriptRef = script; + JSValueRef& exceptionRef = exception; + + Lock syncLock; + Lock& syncLockRef = syncLock; + Condition synchronize; + Condition& synchronizeRef = synchronize; + bool didSynchronize = false; + bool& didSynchronizeRef = didSynchronize; + + std::chrono::microseconds startTime; + std::chrono::microseconds endTime; + + std::chrono::microseconds& startTimeRef = startTime; + std::chrono::microseconds& endTimeRef = endTime; + + dispatch_group_t group = dispatch_group_create(); + dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ + startTimeRef = currentCPUTime(); + JSEvaluateScript(contextRef, scriptRef, nullptr, nullptr, 1, &exceptionRef); + endTimeRef = currentCPUTime(); + auto locker = WTF::holdLock(syncLockRef); + didSynchronizeRef = true; + synchronizeRef.notifyAll(); + }); + + auto locker = holdLock(syncLock); + synchronize.wait(syncLock, [&] { return didSynchronize; }); + + if (((endTime - startTime) < milliseconds(timeAfterWatchdogShouldHaveFired)) && dispatchTerminateCallbackCalled) + printf("PASS: %s script on dispatch queue timed out as expected.\n", tierOptions.tier); + else { + if ((endTime - startTime) >= milliseconds(timeAfterWatchdogShouldHaveFired)) + printf("FAIL: %s script on dispatch queue did not time out as expected.\n", tierOptions.tier); + if (!shouldTerminateCallbackWasCalled) + printf("FAIL: %s script on dispatch queue timeout callback was not called.\n", tierOptions.tier); + failed = true; + } + } +#endif + JSGlobalContextRelease(context); Options::setOptions(savedOptionsBuilder.toString().ascii().data()); diff --git a/API/tests/FunctionOverridesTest.cpp b/API/tests/FunctionOverridesTest.cpp index a325f83..cf0d6dc 100644 --- a/API/tests/FunctionOverridesTest.cpp +++ b/API/tests/FunctionOverridesTest.cpp @@ -29,7 +29,7 @@ #include "FunctionOverrides.h" #include "InitializeThreading.h" #include "JSContextRefPrivate.h" -#include "JavaScriptCore.h" +#include "JavaScript.h" #include "Options.h" #include diff --git a/API/tests/GlobalContextWithFinalizerTest.cpp b/API/tests/GlobalContextWithFinalizerTest.cpp index 0486a26..8dcd515 100644 --- a/API/tests/GlobalContextWithFinalizerTest.cpp +++ b/API/tests/GlobalContextWithFinalizerTest.cpp @@ -26,7 +26,8 @@ #include "config.h" #include "GlobalContextWithFinalizerTest.h" -#include "JavaScriptCore.h" +#include "JavaScript.h" +#include static bool failed = true; diff --git a/API/tests/JSExportTests.mm b/API/tests/JSExportTests.mm index 9d22e3f..1cec939 100644 --- a/API/tests/JSExportTests.mm +++ b/API/tests/JSExportTests.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Apple Inc. All rights reserved. + * Copyright (C) 2014, 2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -80,6 +80,28 @@ extern "C" void checkResult(NSString *description, bool passed); } @end +@interface NoUnderscorePrefix : NSObject +@end + +@implementation NoUnderscorePrefix +@end + +@interface _UnderscorePrefixNoExport : NoUnderscorePrefix +@end + +@implementation _UnderscorePrefixNoExport +@end + +@protocol Initializing +- (instancetype)init; +@end + +@interface _UnderscorePrefixWithExport : NoUnderscorePrefix +@end + +@implementation _UnderscorePrefixWithExport +@end + @implementation JSExportTests + (void) exportInstanceMethodWithIdProtocolTest { @@ -123,15 +145,73 @@ extern "C" void checkResult(NSString *description, bool passed); JSValue *value = [context evaluateScript:@"myString.boolValue()"]; checkResult(@"Dynamically generated JSExport-ed protocols are ignored", [value isUndefined] && !!context.exception); } + ++ (void)classNamePrefixedWithUnderscoreTest +{ + JSContext *context = [[JSContext alloc] init]; + + context[@"_UnderscorePrefixNoExport"] = [_UnderscorePrefixNoExport class]; + context[@"_UnderscorePrefixWithExport"] = [_UnderscorePrefixWithExport class]; + + checkResult(@"Non-underscore-prefixed ancestor class used when there are no exports", [context[@"_UnderscorePrefixNoExport"] toObject] == [NoUnderscorePrefix class]); + checkResult(@"Underscore-prefixed class used when there are exports", [context[@"_UnderscorePrefixWithExport"] toObject] == [_UnderscorePrefixWithExport class]); + + JSValue *withExportInstance = [context evaluateScript:@"new _UnderscorePrefixWithExport()"]; + checkResult(@"Exports present on underscore-prefixed class", !context.exception && !withExportInstance.isUndefined); +} + @end +@protocol AJSExport +- (instancetype)init; +@end + +@interface A : NSObject +@end + +@implementation A +@end + +static void wrapperLifetimeIsTiedToGlobalObject() +{ + JSGlobalContextRef contextRef; + @autoreleasepool { + JSContext *context = [[JSContext alloc] init]; + contextRef = JSGlobalContextRetain(context.JSGlobalContextRef); + context[@"A"] = A.class; + checkResult(@"Initial wrapper's constructor is itself", [[context evaluateScript:@"new A().constructor === A"] toBool]); + } + + @autoreleasepool { + JSContext *context = [JSContext contextWithJSGlobalContextRef:contextRef]; + checkResult(@"New context's wrapper's constructor is itself", [[context evaluateScript:@"new A().constructor === A"] toBool]); + } + + JSGlobalContextRelease(contextRef); +} + +static void wrapperForNSObjectisObject() +{ + @autoreleasepool { + JSContext *context = [[JSContext alloc] init]; + context[@"Object"] = [[NSNull alloc] init]; + context.exception = nil; + + context[@"A"] = NSObject.class; + checkResult(@"Should not throw an exception when wrapping NSObject and Object has been changed", ![context exception]); + } +} + void runJSExportTests() { @autoreleasepool { [JSExportTests exportInstanceMethodWithIdProtocolTest]; [JSExportTests exportInstanceMethodWithClassProtocolTest]; [JSExportTests exportDynamicallyGeneratedProtocolTest]; + [JSExportTests classNamePrefixedWithUnderscoreTest]; } + wrapperLifetimeIsTiedToGlobalObject(); + wrapperForNSObjectisObject(); } #endif // JSC_OBJC_API_ENABLED diff --git a/API/tests/JSONParseTest.cpp b/API/tests/JSONParseTest.cpp index 2797c3c..d7e2bca 100644 --- a/API/tests/JSONParseTest.cpp +++ b/API/tests/JSONParseTest.cpp @@ -39,10 +39,10 @@ int testJSONParse() bool failed = false; RefPtr vm = VM::create(); - + JSLockHolder locker(vm.get()); JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull())); - + ExecState* exec = globalObject->globalExec(); JSValue v0 = JSONParse(exec, ""); JSValue v1 = JSONParse(exec, "#$%^"); @@ -51,7 +51,7 @@ int testJSONParse() JSValue v3 = JSONParse(exec, String(emptyUCharArray, 0)); JSValue v4; JSValue v5 = JSONParse(exec, "123"); - + failed = failed || (v0 != v1); failed = failed || (v1 != v2); failed = failed || (v2 != v3); diff --git a/API/tests/JSObjectGetProxyTargetTest.cpp b/API/tests/JSObjectGetProxyTargetTest.cpp new file mode 100644 index 0000000..282f736 --- /dev/null +++ b/API/tests/JSObjectGetProxyTargetTest.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "JSObjectGetProxyTargetTest.h" + +#include "APICast.h" +#include "InitializeThreading.h" +#include "JSCInlines.h" +#include "JSObjectRefPrivate.h" +#include "JSProxy.h" +#include "JavaScript.h" +#include "Options.h" +#include "ProxyObject.h" + +using namespace JSC; + +int testJSObjectGetProxyTarget() +{ + bool overallResult = true; + + printf("JSObjectGetProxyTargetTest:\n"); + + auto test = [&] (const char* description, bool currentResult) { + printf(" %s: %s\n", description, currentResult ? "PASS" : "FAIL"); + overallResult &= currentResult; + }; + + JSContextGroupRef group = JSContextGroupCreate(); + JSContextRef context = JSGlobalContextCreateInGroup(group, nullptr); + + ExecState* exec = toJS(context); + VM& vm = *toJS(group); + JSObjectRef globalObjectProxy = JSContextGetGlobalObject(context); + JSProxy* globalObjectProxyObject = jsCast(toJS(globalObjectProxy)); + JSGlobalObject* globalObjectObject = jsCast(globalObjectProxyObject->target()); + Structure* proxyStructure = JSProxy::createStructure(vm, globalObjectObject, globalObjectObject->objectPrototype(), PureForwardingProxyType); + JSObjectRef globalObject = toRef(globalObjectObject); + JSProxy* jsProxyObject = JSProxy::create(vm, proxyStructure); + + JSObjectRef array = JSObjectMakeArray(context, 0, nullptr, nullptr); + + Structure* emptyObjectStructure = JSFinalObject::createStructure(vm, globalObjectObject, globalObjectObject->objectPrototype(), 0); + JSObject* handler = JSFinalObject::create(vm, emptyObjectStructure); + ProxyObject* proxyObjectObject = ProxyObject::create(exec, globalObjectObject, toJS(array), handler); + + JSObjectRef jsProxy = toRef(jsProxyObject); + JSObjectRef proxyObject = toRef(proxyObjectObject); + + test("proxy target of null is null", !JSObjectGetProxyTarget(nullptr)); + test("proxy target of non-proxy is null", !JSObjectGetProxyTarget(array)); + test("proxy target of uninitialized JSProxy is null", !JSObjectGetProxyTarget(jsProxy)); + + jsProxyObject->setTarget(vm, globalObjectObject); + + test("proxy target of initialized JSProxy works", JSObjectGetProxyTarget(jsProxy) == globalObject); + + test("proxy target of ProxyObject works", JSObjectGetProxyTarget(proxyObject) == array); + + test("proxy target of GlobalObject is the globalObject", JSObjectGetProxyTarget(globalObjectProxy) == globalObject); + + JSContextGroupRelease(group); + + printf("JSObjectGetProxyTargetTest: %s\n", overallResult ? "PASS" : "FAIL"); + return !overallResult; +} + diff --git a/API/tests/JSObjectGetProxyTargetTest.h b/API/tests/JSObjectGetProxyTargetTest.h new file mode 100644 index 0000000..6fd05a5 --- /dev/null +++ b/API/tests/JSObjectGetProxyTargetTest.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. AND ITS CONTRIBUTORS ``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 ITS 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. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int testJSObjectGetProxyTarget(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/API/tests/MultithreadedMultiVMExecutionTest.cpp b/API/tests/MultithreadedMultiVMExecutionTest.cpp new file mode 100644 index 0000000..b793258 --- /dev/null +++ b/API/tests/MultithreadedMultiVMExecutionTest.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "MultithreadedMultiVMExecutionTest.h" + +#include "InitializeThreading.h" +#include "JSContextRefPrivate.h" +#include "JavaScript.h" +#include "Options.h" +#include +#include +#include +#include +#include + +static int failuresFound = 0; + +static std::vector& threadsList() +{ + static std::vector* list; + static std::once_flag flag; + std::call_once(flag, [] () { + list = new std::vector(); + }); + return *list; +} + +void startMultithreadedMultiVMExecutionTest() +{ + WTF::initializeMainThread(); + JSC::initializeThreading(); + +#define CHECK(condition, message) do { \ + if (!condition) { \ + printf("FAILED MultithreadedMultiVMExecutionTest: %s\n", message); \ + failuresFound++; \ + } \ + } while (false) + + auto task = [&]() { + int ret = 0; + std::string scriptString = + "const AAA = {A:0, B:1, C:2, D:3};" + "class Preconditions { static checkArgument(e,t) { if (!e) throw t }};" + "1 + 2"; + + for (int i = 0; i < 1000; ++i) { + JSClassRef jsClass = JSClassCreate(&kJSClassDefinitionEmpty); + CHECK(jsClass, "global object class creation"); + JSContextGroupRef contextGroup = JSContextGroupCreate(); + CHECK(contextGroup, "group creation"); + JSGlobalContextRef context = JSGlobalContextCreateInGroup(contextGroup, jsClass); + CHECK(context, "ctx creation"); + + JSStringRef jsScriptString = JSStringCreateWithUTF8CString(scriptString.c_str()); + CHECK(jsScriptString, "script to jsString"); + + JSValueRef jsScript = JSEvaluateScript(context, jsScriptString, nullptr, nullptr, 0, nullptr); + CHECK(jsScript, "script eval"); + JSStringRelease(jsScriptString); + + JSGlobalContextRelease(context); + JSContextGroupRelease(contextGroup); + JSClassRelease(jsClass); + } + + return ret; + }; + for (int t = 0; t < 8; ++t) + threadsList().push_back(std::thread(task)); +} + +int finalizeMultithreadedMultiVMExecutionTest() +{ + auto& threads = threadsList(); + for (auto& thread : threads) + thread.join(); + + if (failuresFound) + printf("FAILED MultithreadedMultiVMExecutionTest\n"); + return (failuresFound > 0); +} diff --git a/API/tests/MultithreadedMultiVMExecutionTest.h b/API/tests/MultithreadedMultiVMExecutionTest.h new file mode 100644 index 0000000..6498b67 --- /dev/null +++ b/API/tests/MultithreadedMultiVMExecutionTest.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 Apple Inc. All rights reserved. + * + * 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. AND ITS CONTRIBUTORS ``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 ITS 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. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +extern void startMultithreadedMultiVMExecutionTest(); + +/* Returns 1 if failures were encountered. Else, returns 0. */ +extern int finalizeMultithreadedMultiVMExecutionTest(); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/API/tests/PingPongStackOverflowTest.cpp b/API/tests/PingPongStackOverflowTest.cpp index ef4b914..235dcee 100644 --- a/API/tests/PingPongStackOverflowTest.cpp +++ b/API/tests/PingPongStackOverflowTest.cpp @@ -28,7 +28,7 @@ #include "InitializeThreading.h" #include "JSContextRefPrivate.h" -#include "JavaScriptCore.h" +#include "JavaScript.h" #include "Options.h" #include diff --git a/API/tests/TypedArrayCTest.cpp b/API/tests/TypedArrayCTest.cpp index 8ec8cdd..b81b269 100644 --- a/API/tests/TypedArrayCTest.cpp +++ b/API/tests/TypedArrayCTest.cpp @@ -26,7 +26,10 @@ #include "config.h" #include "TypedArrayCTest.h" -#include "JavaScriptCore.h" +#include "JavaScript.h" +#include +#include +#include #include extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef); diff --git a/API/tests/testapi.c b/API/tests/testapi.c index b6c2451..f12cc2e 100644 --- a/API/tests/testapi.c +++ b/API/tests/testapi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2015-2016 Apple Inc. All rights reserved. + * Copyright (C) 2006-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,13 +25,25 @@ #include +#if USE(CF) #include "JavaScriptCore.h" +#else +#include "JavaScript.h" +#endif + #include "JSBasePrivate.h" #include "JSContextRefPrivate.h" +#include "JSHeapFinalizerPrivate.h" +#include "JSMarkingConstraintPrivate.h" #include "JSObjectRefPrivate.h" #include "JSScriptRefPrivate.h" #include "JSStringRefPrivate.h" +#include "JSWeakPrivate.h" #include +#include +#include +#include +#include #define ASSERT_DISABLED 0 #include @@ -45,6 +57,8 @@ #include "FunctionOverridesTest.h" #include "GlobalContextWithFinalizerTest.h" #include "JSONParseTest.h" +#include "JSObjectGetProxyTargetTest.h" +#include "MultithreadedMultiVMExecutionTest.h" #include "PingPongStackOverflowTest.h" #include "TypedArrayCTest.h" @@ -108,6 +122,7 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa { JSStringRef valueAsString = JSValueToStringCopy(context, value, NULL); +#if USE(CF) size_t jsLength = JSStringGetLength(valueAsString); const JSChar* jsBuffer = JSStringGetCharactersPtr(valueAsString); @@ -134,6 +149,18 @@ static void assertEqualsAsCharactersPtr(JSValueRef value, const char* expectedVa } free(cfBuffer); +#else + size_t bufferSize = JSStringGetMaximumUTF8CStringSize(valueAsString); + char* buffer = (char*)malloc(bufferSize); + JSStringGetUTF8CString(valueAsString, buffer, bufferSize); + + if (strcmp(buffer, expectedValue)) { + fprintf(stderr, "assertEqualsAsCharactersPtr failed: jsBuffer != cfBuffer\n"); + failed = 1; + } + + free(buffer); +#endif JSStringRelease(valueAsString); } @@ -1115,6 +1142,203 @@ static void checkConstnessInJSObjectNames() val.name = "something"; } +#ifdef __cplusplus +extern "C" { +#endif +void JSSynchronousGarbageCollectForDebugging(JSContextRef); +#ifdef __cplusplus +} +#endif + +static const unsigned numWeakRefs = 10000; + +static void markingConstraint(JSMarkerRef marker, void *userData) +{ + JSWeakRef *weakRefs; + unsigned i; + + weakRefs = (JSWeakRef*)userData; + + for (i = 0; i < numWeakRefs; i += 2) { + JSWeakRef weakRef = weakRefs[i]; + if (weakRef) { + JSObjectRef object = JSWeakGetObject(weakRefs[i]); + marker->Mark(marker, object); + assertTrue(marker->IsMarked(marker, object), "A marked object is marked"); + } + } +} + +static bool didRunHeapFinalizer; +static JSContextGroupRef expectedContextGroup; + +static void heapFinalizer(JSContextGroupRef group, void *userData) +{ + assertTrue((uintptr_t)userData == (uintptr_t)42, "Correct userData was passed"); + assertTrue(group == expectedContextGroup, "Correct context group"); + + didRunHeapFinalizer = true; +} + +static void testMarkingConstraintsAndHeapFinalizers(void) +{ + JSContextGroupRef group; + JSContextRef context; + JSWeakRef *weakRefs; + unsigned i; + unsigned deadCount; + + printf("Testing Marking Constraints.\n"); + + group = JSContextGroupCreate(); + expectedContextGroup = group; + + context = JSGlobalContextCreateInGroup(group, NULL); + + weakRefs = (JSWeakRef*)calloc(numWeakRefs, sizeof(JSWeakRef)); + + JSContextGroupAddMarkingConstraint(group, markingConstraint, weakRefs); + JSContextGroupAddHeapFinalizer(group, heapFinalizer, (void*)(uintptr_t)42); + + for (i = numWeakRefs; i--;) + weakRefs[i] = JSWeakCreate(group, JSObjectMakeArray(context, 0, NULL, NULL)); + + JSSynchronousGarbageCollectForDebugging(context); + assertTrue(didRunHeapFinalizer, "Did run heap finalizer"); + + deadCount = 0; + for (i = 0; i < numWeakRefs; i += 2) { + assertTrue(JSWeakGetObject(weakRefs[i]), "Marked objects stayed alive"); + if (!JSWeakGetObject(weakRefs[i + 1])) + deadCount++; + } + + assertTrue(deadCount != 0, "At least some objects died"); + + for (i = numWeakRefs; i--;) { + JSWeakRef weakRef = weakRefs[i]; + weakRefs[i] = NULL; + JSWeakRelease(group, weakRef); + } + + didRunHeapFinalizer = false; + JSSynchronousGarbageCollectForDebugging(context); + assertTrue(didRunHeapFinalizer, "Did run heap finalizer"); + + JSContextGroupRemoveHeapFinalizer(group, heapFinalizer, (void*)(uintptr_t)42); + + didRunHeapFinalizer = false; + JSSynchronousGarbageCollectForDebugging(context); + assertTrue(!didRunHeapFinalizer, "Did not run heap finalizer"); + + JSContextGroupRelease(group); + + printf("PASS: Marking Constraints and Heap Finalizers.\n"); +} + +#if USE(CF) +static void testCFStrings(void) +{ + /* The assertion utility functions we use below expects to get the JSGlobalContextRef + from the global context variable. */ + JSGlobalContextRef oldContext = context; + context = JSGlobalContextCreate(0); + + UniChar singleUniChar = 65; // Capital A + CFMutableStringRef cfString = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault, &singleUniChar, 1, 1, kCFAllocatorNull); + + JSStringRef jsCFIString = JSStringCreateWithCFString(cfString); + JSValueRef jsCFString = JSValueMakeString(context, jsCFIString); + + CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8); + + JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString); + JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString); + + CFIndex cfStringLength = CFStringGetLength(cfString); + UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar)); + CFStringGetCharacters(cfString, CFRangeMake(0, cfStringLength), buffer); + JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength); + JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters); + + JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString)); + free(buffer); + JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters); + + ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString); + ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString); + ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString); + ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString); + + JSStringRef emptyString = JSStringCreateWithCFString(CFSTR("")); + const JSChar* characters = JSStringGetCharactersPtr(emptyString); + if (!characters) { + printf("FAIL: Returned null when accessing character pointer of an empty String.\n"); + failed = 1; + } else + printf("PASS: returned empty when accessing character pointer of an empty String.\n"); + + size_t length = JSStringGetLength(emptyString); + if (length) { + printf("FAIL: Didn't return 0 length for empty String.\n"); + failed = 1; + } else + printf("PASS: returned 0 length for empty String.\n"); + JSStringRelease(emptyString); + + assertEqualsAsBoolean(jsCFString, true); + assertEqualsAsBoolean(jsCFStringWithCharacters, true); + assertEqualsAsBoolean(jsCFEmptyString, false); + assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false); + + assertEqualsAsNumber(jsCFString, nan("")); + assertEqualsAsNumber(jsCFStringWithCharacters, nan("")); + assertEqualsAsNumber(jsCFEmptyString, 0); + assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0); + ASSERT(sizeof(JSChar) == sizeof(UniChar)); + + assertEqualsAsCharactersPtr(jsCFString, "A"); + assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A"); + assertEqualsAsCharactersPtr(jsCFEmptyString, ""); + assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, ""); + + assertEqualsAsUTF8String(jsCFString, "A"); + assertEqualsAsUTF8String(jsCFStringWithCharacters, "A"); + assertEqualsAsUTF8String(jsCFEmptyString, ""); + assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, ""); + + CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString); + CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString); + ASSERT(CFEqual(cfJSString, cfString)); + ASSERT(CFEqual(cfJSEmptyString, cfEmptyString)); + CFRelease(cfJSString); + CFRelease(cfJSEmptyString); + + JSObjectRef o = JSObjectMake(context, NULL, NULL); + JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1"); + JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL); + JSObjectSetProperty(context, o, jsCFIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL); + JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o); + size_t expectedCount = JSPropertyNameArrayGetCount(nameArray); + size_t count; + for (count = 0; count < expectedCount; ++count) + JSPropertyNameArrayGetNameAtIndex(nameArray, count); + JSPropertyNameArrayRelease(nameArray); + ASSERT(count == 1); // jsCFString should not be enumerated + + JSStringRelease(jsOneIString); + JSStringRelease(jsCFIString); + JSStringRelease(jsCFEmptyIString); + JSStringRelease(jsCFIStringWithCharacters); + JSStringRelease(jsCFEmptyIStringWithCharacters); + CFRelease(cfString); + CFRelease(cfEmptyString); + + JSGlobalContextRelease(context); + context = oldContext; +} +#endif + int main(int argc, char* argv[]) { #if OS(WINDOWS) @@ -1125,6 +1349,7 @@ int main(int argc, char* argv[]) #endif testCompareAndSwap(); + startMultithreadedMultiVMExecutionTest(); #if JSC_OBJC_API_ENABLED testObjectiveCAPI(); @@ -1144,6 +1369,12 @@ int main(int argc, char* argv[]) ASSERT(Base_didFinalize); + testMarkingConstraintsAndHeapFinalizers(); + +#if USE(CF) + testCFStrings(); +#endif + JSClassDefinition globalObjectClassDefinition = kJSClassDefinitionEmpty; globalObjectClassDefinition.initialize = globalObject_initialize; globalObjectClassDefinition.staticValues = globalObject_staticValues; @@ -1189,34 +1420,6 @@ int main(int argc, char* argv[]) JSStringRef jsOneIString = JSStringCreateWithUTF8CString("1"); JSValueRef jsOneString = JSValueMakeString(context, jsOneIString); - UniChar singleUniChar = 65; // Capital A - CFMutableStringRef cfString = - CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorDefault, - &singleUniChar, - 1, - 1, - kCFAllocatorNull); - - JSStringRef jsCFIString = JSStringCreateWithCFString(cfString); - JSValueRef jsCFString = JSValueMakeString(context, jsCFIString); - - CFStringRef cfEmptyString = CFStringCreateWithCString(kCFAllocatorDefault, "", kCFStringEncodingUTF8); - - JSStringRef jsCFEmptyIString = JSStringCreateWithCFString(cfEmptyString); - JSValueRef jsCFEmptyString = JSValueMakeString(context, jsCFEmptyIString); - - CFIndex cfStringLength = CFStringGetLength(cfString); - UniChar* buffer = (UniChar*)malloc(cfStringLength * sizeof(UniChar)); - CFStringGetCharacters(cfString, - CFRangeMake(0, cfStringLength), - buffer); - JSStringRef jsCFIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, cfStringLength); - JSValueRef jsCFStringWithCharacters = JSValueMakeString(context, jsCFIStringWithCharacters); - - JSStringRef jsCFEmptyIStringWithCharacters = JSStringCreateWithCharacters((JSChar*)buffer, CFStringGetLength(cfEmptyString)); - free(buffer); - JSValueRef jsCFEmptyStringWithCharacters = JSValueMakeString(context, jsCFEmptyIStringWithCharacters); - JSChar constantString[] = { 'H', 'e', 'l', 'l', 'o', }; JSStringRef constantStringRef = JSStringCreateWithCharactersNoCopy(constantString, sizeof(constantString) / sizeof(constantString[0])); ASSERT(JSStringGetCharactersPtr(constantStringRef) == constantString); @@ -1232,10 +1435,6 @@ int main(int argc, char* argv[]) ASSERT(JSValueGetType(context, jsOneThird) == kJSTypeNumber); ASSERT(JSValueGetType(context, jsEmptyString) == kJSTypeString); ASSERT(JSValueGetType(context, jsOneString) == kJSTypeString); - ASSERT(JSValueGetType(context, jsCFString) == kJSTypeString); - ASSERT(JSValueGetType(context, jsCFStringWithCharacters) == kJSTypeString); - ASSERT(JSValueGetType(context, jsCFEmptyString) == kJSTypeString); - ASSERT(JSValueGetType(context, jsCFEmptyStringWithCharacters) == kJSTypeString); ASSERT(!JSValueIsBoolean(context, NULL)); ASSERT(!JSValueIsObject(context, NULL)); @@ -1258,14 +1457,6 @@ int main(int argc, char* argv[]) } else printf("PASS: returned null when accessing character pointer of a null String.\n"); - JSStringRef emptyString = JSStringCreateWithCFString(CFSTR("")); - characters = JSStringGetCharactersPtr(emptyString); - if (!characters) { - printf("FAIL: Returned null when accessing character pointer of an empty String.\n"); - failed = 1; - } else - printf("PASS: returned empty when accessing character pointer of an empty String.\n"); - size_t length = JSStringGetLength(nullString); if (length) { printf("FAIL: Didn't return 0 length for null String.\n"); @@ -1274,14 +1465,6 @@ int main(int argc, char* argv[]) printf("PASS: returned 0 length for null String.\n"); JSStringRelease(nullString); - length = JSStringGetLength(emptyString); - if (length) { - printf("FAIL: Didn't return 0 length for empty String.\n"); - failed = 1; - } else - printf("PASS: returned 0 length for empty String.\n"); - JSStringRelease(emptyString); - JSObjectRef propertyCatchalls = JSObjectMake(context, PropertyCatchalls_class(context), NULL); JSStringRef propertyCatchallsString = JSStringCreateWithUTF8CString("PropertyCatchalls"); JSObjectSetProperty(context, globalObject, propertyCatchallsString, propertyCatchalls, kJSPropertyAttributeNone, NULL); @@ -1337,7 +1520,8 @@ int main(int argc, char* argv[]) JSGarbageCollect(context); - for (int i = 0; i < 10000; i++) + int i; + for (i = 0; i < 10000; i++) JSObjectMake(context, 0, 0); aHeapRef = JSValueToObject(context, JSObjectGetPrivateProperty(context, myObject, privatePropertyName), 0); @@ -1461,10 +1645,6 @@ int main(int argc, char* argv[]) assertEqualsAsBoolean(jsOneThird, true); assertEqualsAsBoolean(jsEmptyString, false); assertEqualsAsBoolean(jsOneString, true); - assertEqualsAsBoolean(jsCFString, true); - assertEqualsAsBoolean(jsCFStringWithCharacters, true); - assertEqualsAsBoolean(jsCFEmptyString, false); - assertEqualsAsBoolean(jsCFEmptyStringWithCharacters, false); assertEqualsAsNumber(jsUndefined, nan("")); assertEqualsAsNumber(jsNull, 0); @@ -1475,11 +1655,6 @@ int main(int argc, char* argv[]) assertEqualsAsNumber(jsOneThird, 1.0 / 3.0); assertEqualsAsNumber(jsEmptyString, 0); assertEqualsAsNumber(jsOneString, 1); - assertEqualsAsNumber(jsCFString, nan("")); - assertEqualsAsNumber(jsCFStringWithCharacters, nan("")); - assertEqualsAsNumber(jsCFEmptyString, 0); - assertEqualsAsNumber(jsCFEmptyStringWithCharacters, 0); - ASSERT(sizeof(JSChar) == sizeof(UniChar)); assertEqualsAsCharactersPtr(jsUndefined, "undefined"); assertEqualsAsCharactersPtr(jsNull, "null"); @@ -1490,10 +1665,6 @@ int main(int argc, char* argv[]) assertEqualsAsCharactersPtr(jsOneThird, "0.3333333333333333"); assertEqualsAsCharactersPtr(jsEmptyString, ""); assertEqualsAsCharactersPtr(jsOneString, "1"); - assertEqualsAsCharactersPtr(jsCFString, "A"); - assertEqualsAsCharactersPtr(jsCFStringWithCharacters, "A"); - assertEqualsAsCharactersPtr(jsCFEmptyString, ""); - assertEqualsAsCharactersPtr(jsCFEmptyStringWithCharacters, ""); assertEqualsAsUTF8String(jsUndefined, "undefined"); assertEqualsAsUTF8String(jsNull, "null"); @@ -1504,10 +1675,6 @@ int main(int argc, char* argv[]) assertEqualsAsUTF8String(jsOneThird, "0.3333333333333333"); assertEqualsAsUTF8String(jsEmptyString, ""); assertEqualsAsUTF8String(jsOneString, "1"); - assertEqualsAsUTF8String(jsCFString, "A"); - assertEqualsAsUTF8String(jsCFStringWithCharacters, "A"); - assertEqualsAsUTF8String(jsCFEmptyString, ""); - assertEqualsAsUTF8String(jsCFEmptyStringWithCharacters, ""); checkConstnessInJSObjectNames(); @@ -1517,16 +1684,6 @@ int main(int argc, char* argv[]) ASSERT(JSValueIsEqual(context, jsOne, jsOneString, NULL)); ASSERT(!JSValueIsEqual(context, jsTrue, jsFalse, NULL)); - CFStringRef cfJSString = JSStringCopyCFString(kCFAllocatorDefault, jsCFIString); - CFStringRef cfJSEmptyString = JSStringCopyCFString(kCFAllocatorDefault, jsCFEmptyIString); - ASSERT(CFEqual(cfJSString, cfString)); - ASSERT(CFEqual(cfJSEmptyString, cfEmptyString)); - CFRelease(cfJSString); - CFRelease(cfJSEmptyString); - - CFRelease(cfString); - CFRelease(cfEmptyString); - jsGlobalValue = JSObjectMake(context, NULL, NULL); makeGlobalNumberValue(context); JSValueProtect(context, jsGlobalValue); @@ -1680,17 +1837,6 @@ int main(int argc, char* argv[]) JSObjectSetProperty(context, globalObject, string, derived2Constructor, kJSPropertyAttributeNone, NULL); JSStringRelease(string); - o = JSObjectMake(context, NULL, NULL); - JSObjectSetProperty(context, o, jsOneIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeNone, NULL); - JSObjectSetProperty(context, o, jsCFIString, JSValueMakeNumber(context, 1), kJSPropertyAttributeDontEnum, NULL); - JSPropertyNameArrayRef nameArray = JSObjectCopyPropertyNames(context, o); - size_t expectedCount = JSPropertyNameArrayGetCount(nameArray); - size_t count; - for (count = 0; count < expectedCount; ++count) - JSPropertyNameArrayGetNameAtIndex(nameArray, count); - JSPropertyNameArrayRelease(nameArray); - ASSERT(count == 1); // jsCFString should not be enumerated - JSValueRef argumentsArrayValues[] = { JSValueMakeNumber(context, 10), JSValueMakeNumber(context, 20) }; o = JSObjectMakeArray(context, sizeof(argumentsArrayValues) / sizeof(JSValueRef), argumentsArrayValues, NULL); string = JSStringCreateWithUTF8CString("length"); @@ -1814,9 +1960,11 @@ int main(int argc, char* argv[]) ASSERT((!scriptObject) != (!errorMessage)); if (!scriptObject) { printf("FAIL: Test script did not parse\n\t%s:%d\n\t", scriptPath, errorLine); +#if USE(CF) CFStringRef errorCF = JSStringCopyCFString(kCFAllocatorDefault, errorMessage); CFShow(errorCF); CFRelease(errorCF); +#endif JSStringRelease(errorMessage); failed = 1; } @@ -1829,9 +1977,11 @@ int main(int argc, char* argv[]) else { printf("FAIL: Test script returned unexpected value:\n"); JSStringRef exceptionIString = JSValueToStringCopy(context, exception, NULL); +#if USE(CF) CFStringRef exceptionCF = JSStringCopyCFString(kCFAllocatorDefault, exceptionIString); CFShow(exceptionCF); CFRelease(exceptionCF); +#endif JSStringRelease(exceptionIString); failed = 1; } @@ -1889,6 +2039,7 @@ int main(int argc, char* argv[]) failed = testGlobalContextWithFinalizer() || failed; failed = testPingPongStackOverflow() || failed; failed = testJSONParse() || failed; + failed = testJSObjectGetProxyTarget() || failed; // Clear out local variables pointing at JSObjectRefs to allow their values to be collected function = NULL; @@ -1899,10 +2050,6 @@ int main(int argc, char* argv[]) JSStringRelease(jsEmptyIString); JSStringRelease(jsOneIString); - JSStringRelease(jsCFIString); - JSStringRelease(jsCFEmptyIString); - JSStringRelease(jsCFIStringWithCharacters); - JSStringRelease(jsCFEmptyIStringWithCharacters); JSStringRelease(goodSyntax); JSStringRelease(badSyntax); @@ -1941,6 +2088,8 @@ int main(int argc, char* argv[]) globalObjectSetPrototypeTest(); globalObjectPrivatePropertyTest(); + failed = finalizeMultithreadedMultiVMExecutionTest() || failed; + if (failed) { printf("FAIL: Some tests failed.\n"); return 1; diff --git a/API/tests/testapi.mm b/API/tests/testapi.mm index bb69ad0..e98d6cf 100644 --- a/API/tests/testapi.mm +++ b/API/tests/testapi.mm @@ -1468,7 +1468,7 @@ static void testObjectiveCAPIMain() checkResult(@"Ran code in five concurrent VMs that GC'd", ok); } - + currentThisInsideBlockGetterTest(); runDateTests(); runJSExportTests(); @@ -1507,6 +1507,7 @@ static void checkNegativeNSIntegers() checkResult(@"Negative number maintained its original value", [[result toString] isEqualToString:@"-1"]); } + void testObjectiveCAPI() { NSLog(@"Testing Objective-C API"); diff --git a/CMakeLists.txt b/CMakeLists.txt index 968545c..b4b205e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ set(JavaScriptCore_INCLUDE_DIRECTORIES "${JAVASCRIPTCORE_DIR}/dfg" "${JAVASCRIPTCORE_DIR}/disassembler" "${JAVASCRIPTCORE_DIR}/disassembler/udis86" - "${JAVASCRIPTCORE_DIR}/disassembler/arm64" + "${JAVASCRIPTCORE_DIR}/disassembler/ARM64" "${JAVASCRIPTCORE_DIR}/domjit" "${JAVASCRIPTCORE_DIR}/ftl" "${JAVASCRIPTCORE_DIR}/heap" @@ -32,13 +32,12 @@ set(JavaScriptCore_INCLUDE_DIRECTORIES "${JAVASCRIPTCORE_DIR}/llint" "${JAVASCRIPTCORE_DIR}/parser" "${JAVASCRIPTCORE_DIR}/profiler" - "${JAVASCRIPTCORE_DIR}/replay" "${JAVASCRIPTCORE_DIR}/runtime" "${JAVASCRIPTCORE_DIR}/tools" "${JAVASCRIPTCORE_DIR}/wasm" "${JAVASCRIPTCORE_DIR}/wasm/js" "${JAVASCRIPTCORE_DIR}/yarr" - "${DERIVED_SOURCES_DIR}/ForwardingHeaders" + "${FORWARDING_HEADERS_DIR}" "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}" "${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/inspector" ) @@ -55,15 +54,19 @@ set(JavaScriptCore_SOURCES API/JSCallbackObject.cpp API/JSClassRef.cpp API/JSContextRef.cpp + API/JSHeapFinalizerPrivate.cpp + API/JSMarkingConstraintPrivate.cpp API/JSObjectRef.cpp API/JSTypedArray.cpp API/JSScriptRef.cpp API/JSStringRef.cpp API/JSValueRef.cpp API/JSWeakObjectMapRefPrivate.cpp + API/JSWeakPrivate.cpp API/OpaqueJSString.cpp assembler/ARMAssembler.cpp + assembler/AbstractMacroAssembler.cpp assembler/LinkBuffer.cpp assembler/MacroAssembler.cpp assembler/MacroAssemblerARM.cpp @@ -71,37 +74,46 @@ set(JavaScriptCore_SOURCES assembler/MacroAssemblerCodeRef.cpp assembler/MacroAssemblerPrinter.cpp assembler/MacroAssemblerX86Common.cpp + assembler/Printer.cpp - b3/air/AirAllocateStack.cpp + b3/air/AirAllocateRegistersAndStackByLinearScan.cpp + b3/air/AirAllocateRegistersByGraphColoring.cpp + b3/air/AirAllocateStackByGraphColoring.cpp b3/air/AirArg.cpp b3/air/AirBasicBlock.cpp + b3/air/AirBlockInsertionSet.cpp + b3/air/AirBreakCriticalEdges.cpp b3/air/AirCCallSpecial.cpp b3/air/AirCCallingConvention.cpp b3/air/AirCode.cpp b3/air/AirCustom.cpp - b3/air/AirDumpAsJS.cpp + b3/air/AirDisassembler.cpp b3/air/AirEliminateDeadCode.cpp b3/air/AirEmitShuffle.cpp b3/air/AirFixObviousSpills.cpp b3/air/AirFixPartialRegisterStalls.cpp + b3/air/AirFixSpillsAfterTerminals.cpp b3/air/AirGenerate.cpp b3/air/AirGenerated.cpp b3/air/AirHandleCalleeSaves.cpp b3/air/AirInsertionSet.cpp b3/air/AirInst.cpp - b3/air/AirIteratedRegisterCoalescing.cpp b3/air/AirKind.cpp b3/air/AirLogRegisterPressure.cpp b3/air/AirLowerAfterRegAlloc.cpp b3/air/AirLowerEntrySwitch.cpp b3/air/AirLowerMacros.cpp + b3/air/AirLowerStackArgs.cpp b3/air/AirOptimizeBlockOrder.cpp b3/air/AirPadInterference.cpp + b3/air/AirPhaseInsertionSet.cpp b3/air/AirPhaseScope.cpp + b3/air/AirPrintSpecial.cpp + b3/air/AirRegLiveness.cpp b3/air/AirReportUsedRegisters.cpp b3/air/AirSimplifyCFG.cpp b3/air/AirSpecial.cpp - b3/air/AirSpillEverything.cpp + b3/air/AirStackAllocation.cpp b3/air/AirStackSlot.cpp b3/air/AirStackSlotKind.cpp b3/air/AirTmp.cpp @@ -109,6 +121,8 @@ set(JavaScriptCore_SOURCES b3/air/AirValidate.cpp b3/B3ArgumentRegValue.cpp + b3/B3AtomicValue.cpp + b3/B3Bank.cpp b3/B3BasicBlock.cpp b3/B3BlockInsertionSet.cpp b3/B3BreakCriticalEdges.cpp @@ -134,7 +148,6 @@ set(JavaScriptCore_SOURCES b3/B3FoldPathConstants.cpp b3/B3FrequencyClass.cpp b3/B3Generate.cpp - b3/B3HeapRange.cpp b3/B3InferSwitches.cpp b3/B3InsertionSet.cpp b3/B3Kind.cpp @@ -174,9 +187,11 @@ set(JavaScriptCore_SOURCES b3/B3ValueKey.cpp b3/B3ValueRep.cpp b3/B3Variable.cpp + b3/B3VariableLiveness.cpp b3/B3VariableValue.cpp b3/B3WasmAddressValue.cpp b3/B3WasmBoundsCheckValue.cpp + b3/B3Width.cpp bindings/ScriptFunctionCall.cpp bindings/ScriptObject.cpp @@ -185,11 +200,14 @@ set(JavaScriptCore_SOURCES builtins/BuiltinExecutables.cpp builtins/BuiltinExecutableCreator.cpp + bytecode/AccessCase.cpp + bytecode/AccessCaseSnippetParams.cpp bytecode/AdaptiveInferredPropertyValueWatchpointBase.cpp bytecode/ArithProfile.cpp bytecode/ArrayAllocationProfile.cpp bytecode/ArrayProfile.cpp bytecode/BytecodeBasicBlock.cpp + bytecode/BytecodeDumper.cpp bytecode/BytecodeGeneratorification.cpp bytecode/BytecodeIntrinsicRegistry.cpp bytecode/BytecodeLivenessAnalysis.cpp @@ -206,7 +224,6 @@ set(JavaScriptCore_SOURCES bytecode/CodeType.cpp bytecode/ComplexGetStatus.cpp bytecode/DFGExitProfile.cpp - bytecode/DOMJITAccessCasePatchpointParams.cpp bytecode/DataFormat.cpp bytecode/DeferredCompilationCallback.cpp bytecode/DeferredSourceDump.cpp @@ -215,16 +232,20 @@ set(JavaScriptCore_SOURCES bytecode/ExecutionCounter.cpp bytecode/ExitKind.cpp bytecode/ExitingJITType.cpp + bytecode/FullCodeOrigin.cpp bytecode/FunctionCodeBlock.cpp bytecode/GetByIdStatus.cpp bytecode/GetByIdVariant.cpp + bytecode/GetterSetterAccessCase.cpp bytecode/InlineAccess.cpp bytecode/InlineCallFrame.cpp bytecode/InlineCallFrameSet.cpp + bytecode/IntrinsicGetterAccessCase.cpp bytecode/JumpTable.cpp bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp bytecode/LazyOperandValueProfile.cpp bytecode/MethodOfGettingAValueProfile.cpp + bytecode/ModuleNamespaceAccessCase.cpp bytecode/ModuleProgramCodeBlock.cpp bytecode/ObjectPropertyCondition.cpp bytecode/ObjectPropertyConditionSet.cpp @@ -233,6 +254,7 @@ set(JavaScriptCore_SOURCES bytecode/PreciseJumpTargets.cpp bytecode/ProgramCodeBlock.cpp bytecode/PropertyCondition.cpp + bytecode/ProxyableAccessCase.cpp bytecode/PutByIdFlags.cpp bytecode/PutByIdStatus.cpp bytecode/PutByIdVariant.cpp @@ -300,7 +322,6 @@ set(JavaScriptCore_SOURCES dfg/DFGConstantHoistingPhase.cpp dfg/DFGCriticalEdgeBreakingPhase.cpp dfg/DFGDCEPhase.cpp - dfg/DFGDOMJITPatchpointParams.cpp dfg/DFGDesiredIdentifiers.cpp dfg/DFGDesiredTransitions.cpp dfg/DFGDesiredWatchpoints.cpp @@ -335,7 +356,6 @@ set(JavaScriptCore_SOURCES dfg/DFGLazyJSValue.cpp dfg/DFGLazyNode.cpp dfg/DFGLivenessAnalysisPhase.cpp - dfg/DFGLongLivedState.cpp dfg/DFGLoopPreHeaderCreationPhase.cpp dfg/DFGMaximalFlushInsertionPhase.cpp dfg/DFGMayExit.cpp @@ -379,6 +399,7 @@ set(JavaScriptCore_SOURCES dfg/DFGSSAConversionPhase.cpp dfg/DFGSSALoweringPhase.cpp dfg/DFGSafepoint.cpp + dfg/DFGSnippetParams.cpp dfg/DFGSpeculativeJIT.cpp dfg/DFGSpeculativeJIT32_64.cpp dfg/DFGSpeculativeJIT64.cpp @@ -436,7 +457,6 @@ set(JavaScriptCore_SOURCES ftl/FTLCapabilities.cpp ftl/FTLCommonValues.cpp ftl/FTLCompile.cpp - ftl/FTLDOMJITPatchpointParams.cpp ftl/FTLExceptionTarget.cpp ftl/FTLExitArgument.cpp ftl/FTLExitArgumentForOperand.cpp @@ -462,6 +482,7 @@ set(JavaScriptCore_SOURCES ftl/FTLSaveRestore.cpp ftl/FTLSlowPathCall.cpp ftl/FTLSlowPathCallKey.cpp + ftl/FTLSnippetParams.cpp ftl/FTLState.cpp ftl/FTLThunks.cpp ftl/FTLValueRange.cpp @@ -470,6 +491,7 @@ set(JavaScriptCore_SOURCES heap/CellContainer.cpp heap/CodeBlockSet.cpp heap/CollectionScope.cpp + heap/CollectorPhase.cpp heap/ConservativeRoots.cpp heap/DeferGC.cpp heap/DestructionMode.cpp @@ -477,22 +499,21 @@ set(JavaScriptCore_SOURCES heap/FullGCActivityCallback.cpp heap/FreeList.cpp heap/GCActivityCallback.cpp + heap/GCConductor.cpp heap/GCLogging.cpp + heap/GCRequest.cpp heap/HandleSet.cpp heap/HandleStack.cpp heap/Heap.cpp heap/HeapCell.cpp + heap/HeapFinalizerCallback.cpp heap/HeapHelperPool.cpp heap/HeapProfiler.cpp heap/HeapSnapshot.cpp heap/HeapSnapshotBuilder.cpp - heap/HeapStatistics.cpp - heap/HeapTimer.cpp - heap/HeapVerifier.cpp heap/IncrementalSweeper.cpp heap/JITStubRoutineSet.cpp heap/LargeAllocation.cpp - heap/LiveObjectList.cpp heap/MachineStackMarker.cpp heap/MarkStack.cpp heap/MarkedAllocator.cpp @@ -508,6 +529,7 @@ set(JavaScriptCore_SOURCES heap/StopIfNecessaryTimer.cpp heap/Subspace.cpp heap/SynchronousStopTheWorldMutatorScheduler.cpp + heap/Synchronousness.cpp heap/VisitRaceKey.cpp heap/Weak.cpp heap/WeakBlock.cpp @@ -572,7 +594,6 @@ set(JavaScriptCore_SOURCES jit/CallFrameShuffler64.cpp jit/ExecutableAllocationFuzz.cpp jit/ExecutableAllocator.cpp - jit/ExecutableAllocatorFixedVMPool.cpp jit/GCAwareJITStubRoutine.cpp jit/GPRInfo.cpp jit/HostCallReturnValue.cpp @@ -661,7 +682,6 @@ set(JavaScriptCore_SOURCES runtime/ArrayBufferView.cpp runtime/ArrayConstructor.cpp runtime/ArrayConventions.cpp - runtime/ArrayIteratorAdaptiveWatchpoint.cpp runtime/ArrayIteratorPrototype.cpp runtime/ArrayPrototype.cpp runtime/AtomicsObject.cpp @@ -673,6 +693,7 @@ set(JavaScriptCore_SOURCES runtime/BooleanPrototype.cpp runtime/CallData.cpp runtime/CatchScope.cpp + runtime/ClassInfo.cpp runtime/ClonedArguments.cpp runtime/CodeCache.cpp runtime/CodeSpecializationKind.cpp @@ -681,6 +702,7 @@ set(JavaScriptCore_SOURCES runtime/CommonSlowPathsExceptions.cpp runtime/CompilationResult.cpp runtime/Completion.cpp + runtime/ConfigFile.cpp runtime/ConsoleClient.cpp runtime/ConsoleObject.cpp runtime/ConstantMode.cpp @@ -695,6 +717,7 @@ set(JavaScriptCore_SOURCES runtime/DirectArguments.cpp runtime/DirectArgumentsOffset.cpp runtime/DirectEvalExecutable.cpp + runtime/DisallowVMReentry.cpp runtime/DumpContext.cpp runtime/ECMAScriptSpecInternalFunctions.cpp runtime/Error.cpp @@ -729,6 +752,7 @@ set(JavaScriptCore_SOURCES runtime/InitializeThreading.cpp runtime/InspectorInstrumentationObject.cpp runtime/InternalFunction.cpp + runtime/Intrinsic.cpp runtime/IntlCollator.cpp runtime/IntlCollatorConstructor.cpp runtime/IntlCollatorPrototype.cpp @@ -786,12 +810,15 @@ set(JavaScriptCore_SOURCES runtime/JSPromiseDeferred.cpp runtime/JSPromisePrototype.cpp runtime/JSPropertyNameEnumerator.cpp - runtime/JSPropertyNameIterator.cpp runtime/JSProxy.cpp + runtime/JSRunLoopTimer.cpp runtime/JSScope.cpp + runtime/JSScriptFetcher.cpp runtime/JSSegmentedVariableObject.cpp + runtime/JSSegmentedVariableObjectSubspace.cpp runtime/JSSet.cpp runtime/JSSetIterator.cpp + runtime/JSSourceCode.cpp runtime/JSString.cpp runtime/JSStringIterator.cpp runtime/JSStringJoiner.cpp @@ -810,7 +837,6 @@ set(JavaScriptCore_SOURCES runtime/LazyClassStructure.cpp runtime/LiteralParser.cpp runtime/Lookup.cpp - runtime/MapBase.cpp runtime/MapConstructor.cpp runtime/MapIteratorPrototype.cpp runtime/MapPrototype.cpp @@ -830,10 +856,12 @@ set(JavaScriptCore_SOURCES runtime/NumberObject.cpp runtime/NumberPrototype.cpp runtime/ObjectConstructor.cpp + runtime/ObjectInitializationScope.cpp runtime/ObjectPrototype.cpp runtime/Operations.cpp runtime/Options.cpp runtime/ProgramExecutable.cpp + runtime/PromiseDeferredTimer.cpp runtime/PropertyDescriptor.cpp runtime/PropertySlot.cpp runtime/PropertyTable.cpp @@ -892,6 +920,7 @@ set(JavaScriptCore_SOURCES runtime/TypeofType.cpp runtime/VM.cpp runtime/VMEntryScope.cpp + runtime/VMTraps.cpp runtime/VarOffset.cpp runtime/Watchdog.cpp runtime/WeakMapConstructor.cpp @@ -900,10 +929,12 @@ set(JavaScriptCore_SOURCES runtime/WeakSetConstructor.cpp runtime/WeakSetPrototype.cpp + tools/CellList.cpp tools/CodeProfile.cpp tools/CodeProfiling.cpp tools/FunctionOverrides.cpp tools/FunctionWhitelist.cpp + tools/HeapVerifier.cpp tools/JSDollarVM.cpp tools/JSDollarVMPrototype.cpp tools/SigillCrashAnalyzer.cpp @@ -911,18 +942,36 @@ set(JavaScriptCore_SOURCES wasm/JSWebAssembly.cpp wasm/WasmB3IRGenerator.cpp + wasm/WasmBBQPlan.cpp wasm/WasmBinding.cpp + wasm/WasmCallee.cpp wasm/WasmCallingConvention.cpp + wasm/WasmCodeBlock.cpp + wasm/WasmContext.cpp + wasm/WasmFaultSignalHandler.cpp wasm/WasmFormat.cpp + wasm/WasmIndexOrName.cpp + wasm/WasmMachineThreads.cpp wasm/WasmMemory.cpp wasm/WasmMemoryInformation.cpp + wasm/WasmModule.cpp + wasm/WasmModuleInformation.cpp wasm/WasmModuleParser.cpp + wasm/WasmNameSectionParser.cpp + wasm/WasmOMGPlan.cpp + wasm/WasmOpcodeOrigin.cpp + wasm/WasmPageCount.cpp wasm/WasmPlan.cpp + wasm/WasmSignature.cpp + wasm/WasmThunks.cpp wasm/WasmValidate.cpp + wasm/WasmWorklist.cpp - wasm/js/JSWebAssemblyCallee.cpp + wasm/js/JSWebAssemblyCodeBlock.cpp + wasm/js/JSWebAssemblyCodeBlockSubspace.cpp wasm/js/JSWebAssemblyCompileError.cpp wasm/js/JSWebAssemblyInstance.cpp + wasm/js/JSWebAssemblyLinkError.cpp wasm/js/JSWebAssemblyMemory.cpp wasm/js/JSWebAssemblyModule.cpp wasm/js/JSWebAssemblyRuntimeError.cpp @@ -930,8 +979,11 @@ set(JavaScriptCore_SOURCES wasm/js/WebAssemblyCompileErrorConstructor.cpp wasm/js/WebAssemblyCompileErrorPrototype.cpp wasm/js/WebAssemblyFunction.cpp + wasm/js/WebAssemblyFunctionBase.cpp wasm/js/WebAssemblyInstanceConstructor.cpp wasm/js/WebAssemblyInstancePrototype.cpp + wasm/js/WebAssemblyLinkErrorConstructor.cpp + wasm/js/WebAssemblyLinkErrorPrototype.cpp wasm/js/WebAssemblyMemoryConstructor.cpp wasm/js/WebAssemblyMemoryPrototype.cpp wasm/js/WebAssemblyModuleConstructor.cpp @@ -943,6 +995,7 @@ set(JavaScriptCore_SOURCES wasm/js/WebAssemblyTableConstructor.cpp wasm/js/WebAssemblyTablePrototype.cpp wasm/js/WebAssemblyToJSCallee.cpp + wasm/js/WebAssemblyWrapperFunction.cpp yarr/RegularExpression.cpp yarr/YarrCanonicalizeUCS2.cpp @@ -999,6 +1052,8 @@ set(JavaScriptCore_OBJECT_LUT_SOURCES wasm/js/WebAssemblyCompileErrorPrototype.cpp wasm/js/WebAssemblyInstanceConstructor.cpp wasm/js/WebAssemblyInstancePrototype.cpp + wasm/js/WebAssemblyLinkErrorConstructor.cpp + wasm/js/WebAssemblyLinkErrorPrototype.cpp wasm/js/WebAssemblyMemoryConstructor.cpp wasm/js/WebAssemblyMemoryPrototype.cpp wasm/js/WebAssemblyModuleConstructor.cpp @@ -1028,7 +1083,7 @@ set(JavaScriptCore_SCRIPTS_SOURCES_PATHS ) # Force JavaScriptCore to run scripts from the same staging path as WebCore. -set(JavaScriptCore_SCRIPTS_DIR "${DERIVED_SOURCES_DIR}/ForwardingHeaders/JavaScriptCore/Scripts") +set(JavaScriptCore_SCRIPTS_DIR "${FORWARDING_HEADERS_DIR}/JavaScriptCore/Scripts") file(MAKE_DIRECTORY ${JavaScriptCore_SCRIPTS_DIR}) @@ -1084,7 +1139,6 @@ set(OFFLINE_ASM offlineasm/risc.rb offlineasm/self_hash.rb offlineasm/settings.rb - offlineasm/sh4.rb offlineasm/transform.rb offlineasm/x86.rb ) @@ -1150,15 +1204,20 @@ add_custom_command( # since it is used in the add_library() call at the end of this file. if (MSVC) enable_language(ASM_MASM) - list(APPEND JavaScriptCore_SOURCES - ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.asm - ) - # Win32 needs /safeseh with assembly, but Win64 does not. if (CMAKE_SIZEOF_VOID_P EQUAL 4) - set_source_files_properties(${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.asm - PROPERTIES COMPILE_FLAGS "/safeseh" - ) + # Win32 needs /safeseh with assembly, but Win64 does not. + set(MASM_EXECUTABLE ml) + set(LLINT_MASM_FLAGS /safeseh /c /Fo) + else () + set(MASM_EXECUTABLE ml64) + set(LLINT_MASM_FLAGS /c /Fo) endif () + add_custom_command( + OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.obj + DEPENDS ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.asm + COMMAND ${MASM_EXECUTABLE} ${LLINT_MASM_FLAGS} ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.obj ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.asm + VERBATIM) + list(APPEND JavaScriptCore_SOURCES ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LowLevelInterpreterWin.obj) else () list(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntAssembly.h @@ -1167,19 +1226,19 @@ endif () # WebAssembly generator -macro(GENERATE_PYTHON _generator _input _output) +macro(GENERATE_PYTHON _generator _additional_deps _input _output) add_custom_command( OUTPUT ${_output} MAIN_DEPENDENCY ${_generator} - DEPENDS ${_input} + DEPENDS ${_input} ${_additional_deps} COMMAND ${PYTHON_EXECUTABLE} ${_generator} ${_input} ${_output} VERBATIM) list(APPEND JavaScriptCore_HEADERS ${_output}) ADD_SOURCE_DEPENDENCIES(${_input} ${_output}) endmacro() -GENERATE_PYTHON(${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasmOpsHeader.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/wasm.json ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WasmOps.h) -GENERATE_PYTHON(${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasmValidateInlinesHeader.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/wasm.json ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WasmValidateInlines.h) -GENERATE_PYTHON(${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasmB3IRGeneratorInlinesHeader.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/wasm.json ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WasmB3IRGeneratorInlines.h) +GENERATE_PYTHON(${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasmOpsHeader.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasm.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/wasm.json ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WasmOps.h) +GENERATE_PYTHON(${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasmValidateInlinesHeader.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasm.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/wasm.json ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WasmValidateInlines.h) +GENERATE_PYTHON(${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasmB3IRGeneratorInlinesHeader.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/generateWasm.py ${CMAKE_CURRENT_SOURCE_DIR}/wasm/wasm.json ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/WasmB3IRGeneratorInlines.h) # LUT generator @@ -1219,8 +1278,8 @@ set(JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES llint parser profiler - replay runtime + wasm yarr collector/handles @@ -1228,6 +1287,8 @@ set(JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES inspector/agents inspector/augmentable inspector/remote + + wasm/js ) # GENERATOR 1-B: particular LUT creator (for 1 file only) @@ -1286,6 +1347,7 @@ set(JavaScriptCore_INSPECTOR_PROTOCOL_SCRIPTS set(JavaScriptCore_INSPECTOR_DOMAINS ${JAVASCRIPTCORE_DIR}/inspector/protocol/ApplicationCache.json ${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json + ${JAVASCRIPTCORE_DIR}/inspector/protocol/Canvas.json ${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOM.json ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMDebugger.json @@ -1317,12 +1379,6 @@ if (ENABLE_RESOURCE_USAGE) ) endif () -if (ENABLE_WEB_REPLAY) - list(APPEND JavaScriptCore_INSPECTOR_DOMAINS - ${JAVASCRIPTCORE_DIR}/inspector/protocol/Replay.json - ) -endif () - add_custom_command( OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/CombinedDomains.json MAIN_DEPENDENCY ${JavaScriptCore_SCRIPTS_DIR}/generate-combined-inspector-json.py @@ -1442,23 +1498,6 @@ add_custom_command( list(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/InjectedScriptSource.h) -# Web Replay inputs generator -if (ENABLE_WEB_REPLAY) - set(JavaScript_WEB_REPLAY_INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/replay/JSInputs.json) - add_custom_command( - OUTPUT ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSReplayInputs.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSReplayInputs.cpp - MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/replay/scripts/CodeGeneratorReplayInputs.py - DEPENDS ${JavaScript_WEB_REPLAY_INPUTS} - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/replay/scripts/CodeGeneratorReplayInputs.py --outputDir ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/ --framework JavaScriptCore ${JavaScript_WEB_REPLAY_INPUTS} - VERBATIM) - - list(APPEND JavaScriptCore_SOURCES - replay/EncodedValue.cpp - ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSReplayInputs.cpp - ) - list(APPEND JavaScriptCore_HEADERS ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/JSReplayInputs.h) -endif () - if (WTF_CPU_ARM) elseif (WTF_CPU_ARM64) elseif (WTF_CPU_HPPA) @@ -1484,7 +1523,7 @@ else () message(FATAL_ERROR "Unknown CPU") endif () - +WEBKIT_FRAMEWORK_DECLARE(JavaScriptCore) WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS() WEBKIT_CREATE_FORWARDING_HEADERS(JavaScriptCore DIRECTORIES ${JavaScriptCore_FORWARDING_HEADERS_DIRECTORIES} FILES ${JavaScriptCore_FORWARDING_HEADERS_FILES}) diff --git a/ChangeLog b/ChangeLog index 6f8959c..f16bc21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10209 +1,3135 @@ -2017-02-23 Filip Pizlo +2017-08-09 Jason Marcell - verifyEdges should not run in release - + Cherry-pick r220346. rdar://problem/33805219 - Reviewed by Keith Miller and Mark Lam. + 2017-08-07 Commit Queue - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::executeEffects): + Unreviewed, rolling out r220144. + https://bugs.webkit.org/show_bug.cgi?id=175276 -2017-02-23 Filip Pizlo + "It did not actually speed things up in the way I expected" + (Requested by saamyjoon on #webkit). - Disable concurrent GC A:B testing. + Reverted changeset: - * runtime/Options.h: + "On memory-constrained iOS devices, reduce the rate at which + the JS heap grows before a GC to try to keep more memory + available for the system" + https://bugs.webkit.org/show_bug.cgi?id=175041 + http://trac.webkit.org/changeset/220144 -2017-02-17 JF Bastien +2017-08-02 Jason Marcell - A/B test concurrent GC - https://bugs.webkit.org/show_bug.cgi?id=168453 - + Cherry-pick r220144. rdar://problem/33687404 - Reviewed by Phil Pizlo. + 2017-08-02 Saam Barati - The concurrent GC may be causing more crashes, but it's hard to - tell. A/B test this by setting it off for 50% of users, based on - the UUID which crash tracer generates. From this we can look at - crashes and figure out whether the concurrent GC was on or off, - and derive whether fewer crashes occur when it's off. - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - * runtime/Options.h: - -2017-02-21 Matthew Hanson - - Merge r212692. rdar://problem/30475767 - - 2017-02-20 Mark Lam - - [Re-landing] CachedCall should let GC know to keep its arguments alive. - https://bugs.webkit.org/show_bug.cgi?id=168567 - - - Reviewed by Saam Barati. - - 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. - - Update: the original patch has a bug in MarkedArgumentBuffer::expandCapacity() - where it was copying and calling addMarkSet() on values in m_buffer beyond m_size - (up to m_capacity). As a result, depending on the pre-existing values in - m_inlineBuffer, this may result in a computed Heap pointer that is wrong, and - subsequently, manifest as a crash. This is likely to be the cause of the PLT - regression. - - I don't have a new test for this fix because the issue relies on sufficiently bad - values randomly showing up in m_inlineBuffer when we do an ensureCapacity() which - calls expandCapacity(). - - * 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::slowEnsureCapacity): - (JSC::MarkedArgumentBuffer::expandCapacity): - (JSC::MarkedArgumentBuffer::slowAppend): - * runtime/ArgList.h: - (JSC::MarkedArgumentBuffer::append): - (JSC::MarkedArgumentBuffer::ensureCapacity): - * runtime/StringPrototype.cpp: - (JSC::replaceUsingRegExpSearch): - * runtime/VM.cpp: - (JSC::VM::VM): - * runtime/VM.h: - -2017-02-20 Matthew Hanson - - Rollout r212660. rdar://problem/30553220 - -2017-02-20 Matthew Hanson - - Rollout r212646. rdar://problem/30475767 - -2017-02-17 Matthew Hanson - - A/B test concurrent GC - https://bugs.webkit.org/show_bug.cgi?id=168453 - - - Landed on behalf of JF Bastien. - - Reviewed by Alexey Proskuryakov. - - The concurrent GC may be causing more crashes, but it's hard to - tell. A/B test this by setting it off for 50% of users, based on - the UUID which crash tracer generates. From this we can look at - crashes and figure out whether the concurrent GC was on or off, - and derive whether fewer crashes occur when it's off. - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - * runtime/Options.h: - -2017-02-20 Matthew Hanson - - Merge r212618. rdar://problem/30475767 - - 2017-02-19 Mark Lam - - CachedCall should let GC know to keep its arguments alive. - https://bugs.webkit.org/show_bug.cgi?id=168567 - - - Reviewed by Saam Barati. - - 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: - -2017-02-17 Matthew Hanson - - Merge r212177. rdar://problem/30205880 - - 2017-02-10 Saam Barati - - Object allocation sinking phase doesn't properly handle control flow when emitting a PutHint of a materialized object into a PromotedHeapLocation of a still sunken object - https://bugs.webkit.org/show_bug.cgi?id=168140 - + On memory-constrained iOS devices, reduce the rate at which the JS heap grows before a GC to try to keep more memory available for the system + https://bugs.webkit.org/show_bug.cgi?id=175041 + Reviewed by Filip Pizlo. - This patch fixes a bug in allocation sinking phase where - we don't properly handle control flow when materializing - an object and also PutHinting that materialization into - a still sunken object. We were performing the PutHint - for the materialization at the point of materialization, - however, we may have materialized along both edges - of a control flow diamond, in which case, we need to - also PutHint at the join point. Consider this program: - - ``` - bb#0: - b: PhantomActivation() - a: PhantomNewFunction() - c: PutHint(@a, @b, ActivationLoc) - Branch(#1, #2) - - bb#1: - d: MaterializeActivation() - e: PutHint(@a, @d, ActivationLoc) - f: Upsilon(@d, ^p) - Jump(#3) - - bb#2: - g: MaterializeActivation() - h: PutHint(@a, @g, ActivationLoc) - i: Upsilon(@d, ^p) - Jump(#3) - - bb#3: - p: Phi() - // What is PromotedHeapLocation(@a, ActivationLoc) here? - // What would we do if we exited? - ``` - Before this patch, we didn't perform a PutHint of the Phi. - However, we need to, otherwise when exit, we won't know - the value of PromotedHeapLocation(@a, ActivationLoc) - - The program we need then, for correctness, is this: - ``` - bb#0: - b: PhantomActivation() - a: PhantomNewFunction() - c: PutHint(@a, @b, ActivationLoc) - Branch(#1, #2) - - bb#1: - d: MaterializeActivation() - e: PutHint(@a, @d, ActivationLoc) - f: Upsilon(@d, ^p) - Jump(#3) - - bb#2: - g: MaterializeActivation() - h: PutHint(@a, @g, ActivationLoc) - i: Upsilon(@d, ^p) - Jump(#3) - - bb#3: - p: Phi() - j: PutHint(@a, @p, ActivationLoc) - ``` - - This patch makes it so that we emit the necessary PutHint at node `j`. - I've also added more validation to the OSRAvailabilityAnalysisPhase - to catch this problem during validation. - - * dfg/DFGOSRAvailabilityAnalysisPhase.cpp: - (JSC::DFG::OSRAvailabilityAnalysisPhase::run): - * dfg/DFGObjectAllocationSinkingPhase.cpp: - * ftl/FTLOperations.cpp: - (JSC::FTL::operationMaterializeObjectInOSR): - -2017-02-17 Matthew Hanson - - Merge r212035. rdar://problem/30433204 - - 2017-02-09 Filip Pizlo - - SharedArrayBuffer does not need to be in the transfer list - https://bugs.webkit.org/show_bug.cgi?id=168079 - - Reviewed by Geoffrey Garen and Keith Miller. - - Exposes a simple shareWith() API for when you know you want to share the contents of - a shared buffer. Also a useful explicit operator bool. - - * runtime/ArrayBuffer.cpp: - (JSC::ArrayBuffer::shareWith): - * runtime/ArrayBuffer.h: - (JSC::ArrayBufferContents::operator bool): - -2017-02-17 Matthew Hanson - - Merge r212146. rdar://problem/28656664 - - 2017-02-10 Mark Lam - - StructureStubInfo::considerCaching() should write barrier its owner CodeBlock when buffering a new Structure. - https://bugs.webkit.org/show_bug.cgi?id=168137 - - - Reviewed by Filip Pizlo. - - If we're adding a new structure to StructureStubInfo's bufferedStructures, we - should write barrier the StubInfo's owner CodeBlock because that structure may be - collected during the next GC. Write barrier-ing the owner CodeBlock ensures that - CodeBlock::finalizeBaselineJITInlineCaches() is called on it during the GC, - which, in turn, gives the StructureStubInfo the opportunity to filter out the - dead structure. - - * bytecode/StructureStubInfo.h: - (JSC::StructureStubInfo::considerCaching): - * jit/JITOperations.cpp: - -2017-02-16 Keith Miller - - Fix merge issue with r212085 (rdar://problem/29939864). - - * runtime/JSFunction.cpp: - (JSC::JSFunction::callerGetter): - -2017-02-12 Babak Shafiei - - Merge r211609. - - 2017-02-02 Mark Lam - - Add a SIGILL crash analyzer to make debugging SIGILLs easier. - https://bugs.webkit.org/show_bug.cgi?id=167714 - - - Not reviewed. - - Build fix for CLOOP build. - - * tools/VMInspector.cpp: - -2017-02-09 Matthew Hanson - - Merge r212022. rdar://problem/30198083 - - 2017-02-09 Mark Lam - - B3::Procedure::deleteOrphans() should neutralize upsilons with dead phis. - https://bugs.webkit.org/show_bug.cgi?id=167437 - - - Reviewed by Filip Pizlo. - - * b3/B3Procedure.cpp: - (JSC::B3::Procedure::deleteOrphans): - -2017-02-09 Matthew Hanson - - Merge r212021. rdar://problem/30149432 - - 2017-02-09 Saam Barati - - Sloppy mode: We don't properly hoist functions names "arguments" when we have a non-simple parameter list - https://bugs.webkit.org/show_bug.cgi?id=167319 - - - Reviewed by Mark Lam. - - When hoisting a function inside sloppy mode, we were assuming all "var"s are inside - what we call the "var" SymbolTableEntry. This was almost true, execpt for "arguments", - which has sufficiently weird behavior. "arguments" can be visible to the default - parameter expressions inside a function, therefore can't go inside the "var" - SymbolTableEntry since the parameter SymbolTableEntry comes before the "var" - SymbolTableEntry in the scope chain. Therefore, if we hoist a function named - "arguments", then we must also look for that variable inside the parameter scope - stack entry. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::hoistSloppyModeFunctionIfNecessary): - -2017-02-09 Matthew Hanson - - Merge r212019. rdar://problem/30128133 - - 2017-02-09 Mark Lam - - Fix max length check in ArrayPrototype.js' concatSlowPath(). - https://bugs.webkit.org/show_bug.cgi?id=167270 - - - Reviewed by Filip Pizlo. - - 1. Fixed concatSlowPath() to ensure that the result array length does not exceed - @MAX_ARRAY_INDEX. The old code was checking against @MAX_SAFE_INTEGER in some - cases, but this is overly permissive. - - 2. Changed concatSlowPath() to throw a RangeError instead of a TypeError to be - consistent with the C++ runtime functions in JSArray.cpp. - - 3. Changed the RangeError message in concatSlowPath() and JSArray.cpp to "Length - exceeded the maximum array length" when the error is that the result length - exceeds MAX_ARRAY_INDEX. We do this for 2 reasons: - a. "Length exceeded the maximum array length" is more informative than - "Invalid array length". - b. We want to use the same string consistently for the same error. - - There are still 2 places in JSArray.cpp that still throws a RangeError with - message "Invalid array length". In those cases, the error is not necessarily - due to the result length exceeding MAX_ARRAY_INDEX, but is due to attempting to - set a length value that is not an integer that fits in MAX_ARRAY_INDEX e.g. - an attempt to set a fractional length value. Hence, "Invalid array length" is - appropriate for those cases. - - 4. Fixed JSArray::appendMemcpy() to handle overflows when computing the result - array length. - - * builtins/ArrayPrototype.js: - (concatSlowPath): - * bytecode/BytecodeIntrinsicRegistry.cpp: - (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry): - * bytecode/BytecodeIntrinsicRegistry.h: - * runtime/ArrayPrototype.cpp: - (JSC::concatAppendOne): - (JSC::arrayProtoPrivateFuncAppendMemcpy): - * runtime/JSArray.cpp: - (JSC::JSArray::appendMemcpy): - (JSC::JSArray::push): - -2017-02-09 Matthew Hanson - - Merge r212015. rdar://problem/30054759 - - 2017-02-09 Mark Lam - - Constructed object's global object should be the global object of the constructor. - https://bugs.webkit.org/show_bug.cgi?id=167121 - - - Reviewed by Filip Pizlo and Geoffrey Garen. - - The realm (i.e. globalObject) of any object should be the same as the constructor - that instantiated the object. Changed PrototypeMap::createEmptyStructure() to - be passed the correct globalObject to use instead of assuming it's the same one - as the prototype object. - - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::finishCreation): - * bytecode/InternalFunctionAllocationProfile.h: - (JSC::InternalFunctionAllocationProfile::createAllocationStructureFromBase): - * bytecode/ObjectAllocationProfile.h: - (JSC::ObjectAllocationProfile::initialize): - * runtime/FunctionRareData.cpp: - (JSC::FunctionRareData::initializeObjectAllocationProfile): - * runtime/FunctionRareData.h: - (JSC::FunctionRareData::createInternalFunctionAllocationStructureFromBase): - * runtime/InternalFunction.cpp: - (JSC::InternalFunction::createSubclassStructure): - * runtime/IteratorOperations.cpp: - (JSC::createIteratorResultObjectStructure): - * runtime/JSBoundFunction.cpp: - (JSC::getBoundFunctionStructure): - * runtime/JSFunction.cpp: - (JSC::JSFunction::allocateAndInitializeRareData): - (JSC::JSFunction::initializeRareData): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::init): - * runtime/JSProxy.cpp: - (JSC::JSProxy::setTarget): - * runtime/ObjectConstructor.h: - (JSC::constructEmptyObject): - * runtime/PrototypeMap.cpp: - (JSC::PrototypeMap::createEmptyStructure): - (JSC::PrototypeMap::emptyStructureForPrototypeFromBaseStructure): - (JSC::PrototypeMap::emptyObjectStructureForPrototype): - (JSC::PrototypeMap::clearEmptyObjectStructureForPrototype): - * runtime/PrototypeMap.h: - -2017-02-09 Matthew Hanson - - Merge r212009. rdar://problem/29939864 - - 2017-02-09 Keith Miller - - We should not allow Function.caller to be used on native functions - https://bugs.webkit.org/show_bug.cgi?id=165628 - - Reviewed by Mark Lam. - - Also remove unneeded dynamic cast. - - * runtime/JSFunction.cpp: - (JSC::RetrieveCallerFunctionFunctor::RetrieveCallerFunctionFunctor): - (JSC::JSFunction::callerGetter): - -2017-02-09 Matthew Hanson - - Merge r211622. rdar://problem/30116072 - - 2017-02-02 Andreas Kling - - [Mac] In-process memory pressure monitor for WebContent processes AKA websam - - - - Reviewed by Antti Koivisto. - - Remove the sloppy "max live heap size" mechanism from JSC in favor of the new - WebCore-side memory footprint monitor. + The testing I have done shows that this new function is a ~10% + progression running JetStream on 1GB iOS devices. I've also tried + this on a few > 1GB iOS devices, and the testing shows this is either neutral + or a regression. Right now, we'll just enable this for <= 1GB devices + since it's a win. In the future, we might want to either look into + tweaking these parameters or coming up with a new function for > 1GB + devices. * heap/Heap.cpp: - (JSC::Heap::updateAllocationLimits): - (JSC::Heap::didExceedMaxLiveSize): Deleted. - * heap/Heap.h: - (JSC::Heap::setMaxLiveSize): Deleted. - -2017-02-09 Matthew Hanson - - Merge r211896. rdar://problem/29754721 - - 2017-02-08 Saam Barati - - Air IRC might spill a terminal that produces a value after the terminal - https://bugs.webkit.org/show_bug.cgi?id=167919 - - - Reviewed by Filip Pizlo. - - IRC may spill a value-producing terminal (a patchpoint can be a value-producing terminal). - It used to do this by placing the spill *after* the terminal. This produces an invalid - graph because no instructions are allowed after the terminal. - - I fixed this bug by having a cleanup pass over the IR after IRC is done. - The pass detects this problem, and fixes it by moving the spill into the - successors. However, it is careful to detect when the edge to the - successor is a critical edge. If the value-producing patchpoint is - the only predecessor of the successor, it just moves the spill - code to the beginning of the successor. Otherwise, it's a critical - edge and it breaks it by adding a block that does the spilling then - jumps to the successor. - - * b3/air/AirInsertionSet.cpp: - * b3/air/AirInsertionSet.h: - (JSC::B3::Air::InsertionSet::insertInsts): - * b3/air/AirIteratedRegisterCoalescing.cpp: - * b3/testb3.cpp: - (JSC::B3::testTerminalPatchpointThatNeedsToBeSpilled): - (JSC::B3::testTerminalPatchpointThatNeedsToBeSpilled2): - (JSC::B3::run): - -2017-02-09 Matthew Hanson - - Merge r211642. rdar://problem/29542720 - - 2017-02-03 Saam Barati - - When OSR entering to the baseline JIT from the LLInt for a ProgramCodeBlock we can skip compiling a lot of the program - https://bugs.webkit.org/show_bug.cgi?id=167725 - - - Reviewed by Michael Saboff. - - We often want to baseline compile ProgramCode once we hit a loop in the LLInt. - However, some programs execute a non-trivial amount of code before the loop. - This code can never be executed again because ProgramCodeBlocks never run more - than once. We're wasting time and memory by compiling code that is unreachable - from the OSR entry destination. This patch fixes this by only compiling code - that is reachable from the OSR entry destination. - - This is a speedup on Kraken/ai-astar for devices with limited CPUs (I've been - testing on devices with 2 CPUs). On ai-astar, we were spending 50-100ms compiling - a huge ProgramCodeBlock in the baseline JIT where the majority of the code - would never execute. If this compilation was kicked off on the main thread, - then we'd be stalled for a long time. If it were started on the baseline JITs - background compilation thread, we'd still waste 50-100ms in that thread, causing - all other baseline compilations to happen on the main thread. - - * interpreter/Interpreter.cpp: - (JSC::Interpreter::executeProgram): - * interpreter/Interpreter.h: - * jit/JIT.cpp: - (JSC::JIT::JIT): - (JSC::JIT::privateCompileMainPass): - * jit/JIT.h: - (JSC::JIT::compile): - * jit/JITWorklist.cpp: - (JSC::JITWorklist::Plan::Plan): - (JSC::JITWorklist::Plan::compileNow): - (JSC::JITWorklist::compileLater): - (JSC::JITWorklist::compileNow): - * jit/JITWorklist.h: - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::jitCompileAndSetHeuristics): - (JSC::LLInt::LLINT_SLOW_PATH_DECL): - * runtime/Completion.cpp: - (JSC::evaluate): - -2017-02-09 Matthew Hanson - - Merge r211603. rdar://problem/30318237 - - 2017-02-02 Mark Lam - - Add a SIGILL crash analyzer to make debugging SIGILLs easier. - https://bugs.webkit.org/show_bug.cgi?id=167714 - - - Reviewed by Filip Pizlo. - - The current implementation is only for X86_64 and ARM64 on OS(DARWIN). The - analyzer is not enabled for all other ports. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * API/JSVirtualMachine.mm: - * assembler/ARM64Assembler.h: - (JSC::ARM64Assembler::illegalInstruction): - * assembler/MacroAssemblerARM64.h: - (JSC::MacroAssemblerARM64::illegalInstruction): - * assembler/MacroAssemblerX86Common.h: - (JSC::MacroAssemblerX86Common::illegalInstruction): - * assembler/X86Assembler.h: - (JSC::X86Assembler::illegalInstruction): - * heap/Heap.cpp: - (JSC::Heap::forEachCodeBlockIgnoringJITPlansImpl): - * heap/Heap.h: - * heap/HeapInlines.h: - (JSC::Heap::forEachCodeBlockIgnoringJITPlans): - * runtime/Options.cpp: - (JSC::Options::isAvailable): - (JSC::recomputeDependentOptions): * runtime/Options.h: - * runtime/VM.cpp: - (JSC::VM::VM): - (JSC::VM::~VM): - * runtime/VM.h: - * tools/SigillCrashAnalyzer.cpp: Added. - (JSC::SignalContext::SignalContext): - (JSC::SignalContext::dump): - (JSC::handleCrash): - (JSC::initializeCrashHandler): - (JSC::ensureSigillCrashAnalyzer): - (JSC::SigillCrashAnalyzer::analyze): - (JSC::SigillCrashAnalyzer::dumpCodeBlock): - * tools/SigillCrashAnalyzer.h: Added. - * tools/VMInspector.cpp: Added. - (JSC::VMInspector::instance): - (JSC::VMInspector::add): - (JSC::VMInspector::remove): - (JSC::ensureIsSafeToLock): - * tools/VMInspector.h: Added. - (JSC::VMInspector::iterate): -2017-02-06 Matthew Hanson +2017-07-31 Jason Marcell - Merge r211666. rdar://problem/30167791 + Cherry-pick r220012. rdar://problem/33619526 - 2017-02-03 Joseph Pecoraro + 2017-07-28 Mark Lam - Unreviewed rollout of r211486, r211629. - - Original change is not ideal and is causing issues. - - * inspector/agents/InspectorHeapAgent.cpp: - (Inspector::SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask): - * runtime/InitializeThreading.cpp: - (JSC::initializeThreading): - -2017-02-05 Matthew Hanson - - Merge r211630. rdar://problem/30318237 - - 2017-02-03 Csaba Osztrogonác - - [cmake] Unreviewed AArch64 buildfix after r211603. - https://bugs.webkit.org/show_bug.cgi?id=167714 - - * CMakeLists.txt: - -2017-02-05 Matthew Hanson - - Merge r211658. rdar://problem/29144126 - - 2017-02-03 JF Bastien - - OSR entry: delay outer-loop compilation when at inner-loop - https://bugs.webkit.org/show_bug.cgi?id=167149 + ObjectToStringAdaptiveStructureWatchpoint should not fire if it's dying imminently. + https://bugs.webkit.org/show_bug.cgi?id=174948 + Reviewed by Filip Pizlo. - r211224 and r211461 were reverted because they caused massive - kraken/ai-astar regressions. This patch instead does the - minimally-disruptive change to fix the original bug as described - below, but omits extra tuning and refactoring which I had - before. I'll commit tuning and refactoring separately, if this - sticks. This patch is therefore very minimal, and layers carefully - on top of the complex spaghetti-logic. The only change it makes is - that it uses triggers to indicate to outer loops that they should - compile, which fixes the immediate bug and seems roughly perf - neutral (maybe a small gain on kraken sometimes, other times a - small regression as would be expected from slightly compiling - later). As opposed to r211461 this patch doesn't unconditionally - unset the trigger because it prevents further DFG executions from - entering. It therefore makes the trigger a tri-state enum class: - don't trigger, compilation done, start compilation. Only "start - compilation" gets reset to "don't trigger". "Compilation done" - does not (unless there's a problem compiling, then it gets set - back to "don't trigger"). + ObjectToStringAdaptiveStructureWatchpoint is owned by StructureRareData. If its + owner StructureRareData is already known to be dead (in terms of GC liveness) but + hasn't been destructed yet (i.e. not swept by the GC yet), we should ignore all + requests to fire this watchpoint. - As of https://bugs.webkit.org/show_bug.cgi?id=155217 OSR - compilation can be kicked off for an entry into an outer-loop, - while executing an inner-loop. This is desirable because often the - codegen from an inner-entry isn't as good as the codegen from an - outer-entry, but execution from an inner-loop is often pretty hot - and likely to kick off compilation. This approach provided nice - speedups on Kraken because we'd select to enter to the outer-loop - very reliably, which reduces variability (the inner-loop was - selected roughly 1/5 times from my unscientific measurements). + If the GC had the chance to sweep the StructureRareData, thereby destructing the + ObjectToStringAdaptiveStructureWatchpoint, it (the watchpoint) would have removed + itself from the WatchpointSet it was on. Hence, it would not have been fired. - When compilation starts we take a snapshot of the JSValues at the - current execution state using OSR's recovery mechanism. These - values are passed to the compiler and are used as way to perform - type profiling, and could be used to observe cell types as well as - to perform predictions such as through constant propagation. + But since the watchpoint hasn't been destructed yet, it still remains on the + WatchpointSet and needs to guard against being fired in this state. The fix is + to simply return early if its owner StructureRareData is not live. This has the + effect of the watchpoint fire being a no-op, which is equivalent to the watchpoint + not firing as we would expect. - It's therefore desired to enter from the outer-loop when we can, - but we need to be executing from that location to capture the - right JSValues, otherwise we're confusing the compiler and giving - it inaccurate JSValues which can lead it to predict the wrong - things, leading to suboptimal code or recompilation due to - misprediction, or in super-corner-cases a crash. + This patch also removes some cargo cult copying of watchpoint code which + instantiates a StringFireDetail. In a few cases, that StringFireDetail is never + used. This patch removes these unnecessary instantiations. - DFG tier-up was added here: - https://bugs.webkit.org/show_bug.cgi?id=112838 + * bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp: + (JSC::LLIntPrototypeLoadAdaptiveStructureWatchpoint::fireInternal): + * runtime/StructureRareData.cpp: + (JSC::ObjectToStringAdaptiveStructureWatchpoint::fireInternal): + (JSC::ObjectToStringAdaptiveInferredPropertyValueWatchpoint::handleFire): - * dfg/DFGJITCode.h: - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::JITCompiler): - * dfg/DFGOperations.cpp: - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp: - (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback): - (JSC::DFG::RefToFTLForOSREntryDeferredCompilationCallback::create): - (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously): - (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete): - * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h: +2017-07-28 Jason Marcell -2017-02-02 Matthew Hanson + Cherry-pick r219895. rdar://problem/33595450 - Merge r211486. rdar://problem/30167791 + 2017-07-25 Keith Miller - 2017-02-01 Joseph Pecoraro - - Web Inspector: Use guaranteed RunLoop instead of RunLoop::current for dispatching inspector GC event - https://bugs.webkit.org/show_bug.cgi?id=167683 - - - Reviewed by Timothy Hatcher. - - * inspector/agents/InspectorHeapAgent.cpp: - (Inspector::SendGarbageCollectionEventsTask::SendGarbageCollectionEventsTask): - Use RunLoop::main instead of RunLoop::current which may go away. - - * runtime/InitializeThreading.cpp: - (JSC::initializeThreading): - Ensure RunLoop::main is initialized when using JSC APIs. - -2017-02-02 Matthew Hanson - - Merge r211463. rdar://problem/30296879 - - 2017-01-31 Filip Pizlo - - Make verifyEdge a RELEASE_ASSERT - - - Rubber stamped by Saam Barati. - - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::executeEffects): - -2017-01-31 Matthew Hanson - - Merge r211385. rdar://problem/29738502 - - 2017-01-30 Matt Baker - - Web Inspector: Need some limit on Async Call Stacks for async loops (rAF loops) - https://bugs.webkit.org/show_bug.cgi?id=165633 - - - Reviewed by Joseph Pecoraro. - - This patch limits the memory used by the Inspector backend to store async - stack trace data. - - Asynchronous stack traces are stored as a disjoint set of parent pointer - trees. Tree nodes represent asynchronous operations, and hold a copy of - the stack trace at the time the operation was scheduled. Each tree can - be regarded as a set of stack traces, stored as singly linked lists that - share part of their structure (specifically their tails). Traces belonging - to the same tree will at least share a common root. A stack trace begins - at a leaf node and follows the chain of parent pointers to the root of - of the tree. Leaf nodes always contain pending asynchronous calls. - - When an asynchronous operation is scheduled with requestAnimationFrame, - setInterval, etc, a node is created containing the current call stack and - some bookkeeping data for the operation. An unique identifier comprised - of an operation type and callback identifier is mapped to the node. If - scheduling the callback was itself the result of an asynchronous call, - the node becomes a child of the node associated with that call, otherwise - it becomes the root of a new tree. - - A node is either `pending`, `active`, `dispatched`, or `canceled`. Nodes - start out as pending. After a callback for a pending node is dispatched - the node is marked as such, unless it is a repeating callback such as - setInterval, in which case it remains pending. Once a node is no longer - pending it is removed, as long as it has no children. Since nodes are - reference counted, it is a property of the stack trace tree that nodes - that are no longer pending and have no children pointing to them will be - automatically pruned from the tree. - - If an async operation is canceled (e.g. cancelTimeout), the associated - node is marked as such. If the callback is not being dispatched at the - time, and has no children, it is removed. - - Because async operations can be chained indefinitely, stack traces are - limited to a maximum depth. The depth of a stack trace is equal to the - sum of the depths of its nodes, with a node's depth equal to the number - of frames in its associated call stack. For any stack trace, - - S = { sퟶ, sퟷ, …, s푘 }, with endpoints sퟶ, s푘 - depth(S) = depth(sퟶ) + depth(sퟷ) + … + depth(s푘) - - A stack trace is truncated when it exceeds the maximum depth. Truncation - occurs on node boundaries, not call frames, consequently the maximum depth - is more of a target than a guarantee: - - d = maximum stack trace depth - for all S, depth(S) ≤ d + depth(s푘) - - Because nodes can belong to multiple stack traces, it may be necessary - to clone the tail of a stack trace being truncated to prevent other traces - from being effected. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * inspector/AsyncStackTrace.cpp: Added. - (Inspector::AsyncStackTrace::create): - (Inspector::AsyncStackTrace::AsyncStackTrace): - (Inspector::AsyncStackTrace::~AsyncStackTrace): - (Inspector::AsyncStackTrace::isPending): - (Inspector::AsyncStackTrace::isLocked): - (Inspector::AsyncStackTrace::willDispatchAsyncCall): - (Inspector::AsyncStackTrace::didDispatchAsyncCall): - (Inspector::AsyncStackTrace::didCancelAsyncCall): - (Inspector::AsyncStackTrace::buildInspectorObject): - (Inspector::AsyncStackTrace::truncate): - (Inspector::AsyncStackTrace::remove): - * inspector/AsyncStackTrace.h: - * inspector/agents/InspectorDebuggerAgent.cpp: - (Inspector::InspectorDebuggerAgent::didScheduleAsyncCall): - (Inspector::InspectorDebuggerAgent::didCancelAsyncCall): - (Inspector::InspectorDebuggerAgent::willDispatchAsyncCall): - (Inspector::InspectorDebuggerAgent::didDispatchAsyncCall): - (Inspector::InspectorDebuggerAgent::didPause): - (Inspector::InspectorDebuggerAgent::clearAsyncStackTraceData): - (Inspector::InspectorDebuggerAgent::buildAsyncStackTrace): Deleted. - (Inspector::InspectorDebuggerAgent::refAsyncCallData): Deleted. - (Inspector::InspectorDebuggerAgent::derefAsyncCallData): Deleted. - * inspector/agents/InspectorDebuggerAgent.h: - * inspector/protocol/Console.json: - -2017-01-31 Matthew Hanson - - Merge r211300. rdar://problem/30135571 - - 2017-01-27 Filip Pizlo - - scanExternalRememberedSet needs to mergeIfNecessary - https://bugs.webkit.org/show_bug.cgi?id=167523 - - Reviewed by Keith Miller. - - The protocol for opaque roots is that if you add to them outside of draining, then you need to call - mergeIfNecessary. - - This means that every MarkingConstraint that adds opaque roots needs to mergeIfNecessary after. - - scanExternalRememberedSet transitively calls addOpaqueRoot, is called from a MarkingConstraint, and - was missing a call to mergeIfNecessary. This fixes it. - - * API/JSVirtualMachine.mm: - (scanExternalRememberedSet): - -2017-01-27 Matthew Hanson - - Merge r211194. rdar://problem/30201008 - - 2017-01-25 Filip Pizlo - - jsc.cpp should have the $.agent stuff for testing SAB - https://bugs.webkit.org/show_bug.cgi?id=167431 + Remove Broken CompareEq constant folding phase. + https://bugs.webkit.org/show_bug.cgi?id=174846 + Reviewed by Saam Barati. - This adds some stuff that the SAB branch of test262 needs. None of this is exposed except for our - own tests and the SAB branch of test262. We now pass all of the Atomics tests in the SAB branch - of test262. + This bug happened when we would get code like the following: - * jsc.cpp: - (Message::releaseContents): - (Message::index): - (GlobalObject::finishCreation): - (GlobalObject::addFunction): - (Message::Message): - (Message::~Message): - (Worker::Worker): - (Worker::~Worker): - (Worker::send): - (Worker::receive): - (Worker::current): - (Worker::currentWorker): - (Workers::Workers): - (Workers::~Workers): - (Workers::broadcast): - (Workers::report): - (Workers::tryGetReport): - (Workers::getReport): - (Workers::singleton): - (functionDollarCreateRealm): - (functionDollarDetachArrayBuffer): - (functionDollarEvalScript): - (functionDollarAgentStart): - (functionDollarAgentReceiveBroadcast): - (functionDollarAgentReport): - (functionDollarAgentSleep): - (functionDollarAgentBroadcast): - (functionDollarAgentGetReport): - (functionWaitForReport): - (checkException): - (runWithScripts): - (runJSC): - (jscmain): - * runtime/JSArrayBuffer.h: + a: JSConst(Undefined) + b: GetLocal(SomeObjectOrUndefined) + ... + c: CompareEq(Check:ObjectOrOther:b, Check:ObjectOrOther:a) -2017-01-27 Matthew Hanson + constant folding will turn this into: - Rollout r211258. rdar://problem/29144126 + a: JSConst(Undefined) + b: GetLocal(SomeObjectOrUndefined) + ... + c: CompareEq(Check:ObjectOrOther:b, Other:a) -2017-01-27 Matthew Hanson + But the SpeculativeJIT/FTL lowering will fail to check b + properly which leads to an assertion failure in the AI. - Merge r211237. rdar://problem/30179506 + I'll follow up with a more robust fix later. For now, I'll remove the + case that generates the code. Removing the code appears to be perf + neutral. - 2017-01-26 Saam Barati - - Harden how the compiler references GC objects - https://bugs.webkit.org/show_bug.cgi?id=167277 - - - Reviewed by Filip Pizlo. - - Since r210971, the DFG/FTL will flash safepoints before - each phase. This means that there are more opportunities for - a GC to happen while the compiler is running. Because of this, - the compiler must keep track of all the heap pointers that are part - of the Graph data structure. To accomplish this, I've designed - a new type called RegisteredStructure that can only be constructed - after the Graph becomes aware of its underlying Structure*. I - designed this new type to have the type system in C++ help us catch - errors where we're not informing the graph/plan of a heap pointer. - I've made it a compile error to create an OpInfo with a pointer - T* where T inherits from HeapCell. This encourages an OpInfo - to be created with either a FrozenValue* or a RegisteredStructure. - I've added similar compile time assertions for TrustedImmPtr in DFG::SpeculativeJIT - and FTL::Output::constIntPtr. These static asserts don't save us from all bad - programs because there are ways to write code that's incorrect that compiles, - but the new types do help us ensure that the most obvious way of writing the - code is correct. - - The reason this patch is so big is that I've strung RegisteredStructure and - RegisteredStructureSet through the entire DFG/FTL. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::determineLiveness): - * bytecode/StructureSet.cpp: - (JSC::StructureSet::filter): Deleted. - (JSC::StructureSet::filterArrayModes): Deleted. - (JSC::StructureSet::speculationFromStructures): Deleted. - (JSC::StructureSet::arrayModesFromStructures): Deleted. - (JSC::StructureSet::validateReferences): Deleted. - * bytecode/StructureSet.h: - * dfg/DFGAbstractInterpreter.h: - (JSC::DFG::AbstractInterpreter::filter): - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::booleanResult): - (JSC::DFG::isToThisAnIdentity): - (JSC::DFG::AbstractInterpreter::executeEffects): - (JSC::DFG::AbstractInterpreter::observeTransition): - (JSC::DFG::AbstractInterpreter::filter): - * dfg/DFGAbstractValue.cpp: - (JSC::DFG::AbstractValue::set): - (JSC::DFG::AbstractValue::setType): - (JSC::DFG::AbstractValue::mergeOSREntryValue): - (JSC::DFG::AbstractValue::filter): - (JSC::DFG::AbstractValue::changeStructure): - (JSC::DFG::AbstractValue::contains): - * dfg/DFGAbstractValue.h: - (JSC::DFG::AbstractValue::observeTransition): - (JSC::DFG::AbstractValue::TransitionObserver::TransitionObserver): - * dfg/DFGArgumentsEliminationPhase.cpp: - * dfg/DFGArrayMode.cpp: - (JSC::DFG::ArrayMode::alreadyChecked): - * dfg/DFGArrayifySlowPathGenerator.h: - (JSC::DFG::ArrayifySlowPathGenerator::ArrayifySlowPathGenerator): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleConstantInternalFunction): - (JSC::DFG::ByteCodeParser::load): - (JSC::DFG::ByteCodeParser::handleGetById): - (JSC::DFG::ByteCodeParser::handlePutById): - (JSC::DFG::ByteCodeParser::parseBlock): - (JSC::DFG::ByteCodeParser::InlineStackEntry::InlineStackEntry): - * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: - (JSC::DFG::CallArrayAllocatorSlowPathGenerator::CallArrayAllocatorSlowPathGenerator): - (JSC::DFG::CallArrayAllocatorWithVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableSizeSlowPathGenerator): - * dfg/DFGCallCreateDirectArgumentsSlowPathGenerator.h: - (JSC::DFG::CallCreateDirectArgumentsSlowPathGenerator::CallCreateDirectArgumentsSlowPathGenerator): - * dfg/DFGCommonData.cpp: - (JSC::DFG::CommonData::notifyCompilingStructureTransition): * dfg/DFGConstantFoldingPhase.cpp: (JSC::DFG::ConstantFoldingPhase::foldConstants): - (JSC::DFG::ConstantFoldingPhase::emitGetByOffset): - (JSC::DFG::ConstantFoldingPhase::emitPutByOffset): - (JSC::DFG::ConstantFoldingPhase::addBaseCheck): - (JSC::DFG::ConstantFoldingPhase::addStructureTransitionCheck): - * dfg/DFGDesiredWeakReferences.cpp: - (JSC::DFG::DesiredWeakReferences::reallyAdd): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::checkArray): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::Graph): - (JSC::DFG::Graph::dump): - (JSC::DFG::Graph::tryGetConstantProperty): - (JSC::DFG::Graph::inferredValueForProperty): - (JSC::DFG::Graph::visitChildren): - (JSC::DFG::Graph::freeze): - (JSC::DFG::Graph::registerStructure): - (JSC::DFG::Graph::assertIsRegistered): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::registerStructure): - (JSC::DFG::Graph::addStructureSet): - * dfg/DFGJITCompiler.h: - (JSC::DFG::JITCompiler::branchWeakStructure): - * dfg/DFGMultiGetByOffsetData.cpp: - (JSC::DFG::MultiGetByOffsetCase::dumpInContext): - * dfg/DFGMultiGetByOffsetData.h: - (JSC::DFG::MultiGetByOffsetCase::MultiGetByOffsetCase): - (JSC::DFG::MultiGetByOffsetCase::set): - * dfg/DFGNode.cpp: - (JSC::DFG::Node::convertToPutStructureHint): - * dfg/DFGNode.h: - (JSC::DFG::Node::convertToCheckStructure): - (JSC::DFG::Node::structureSet): - (JSC::DFG::Node::structure): - (JSC::DFG::Node::OpInfoWrapper::OpInfoWrapper): - (JSC::DFG::Node::OpInfoWrapper::operator=): - (JSC::DFG::Node::OpInfoWrapper::asRegisteredStructure): - * dfg/DFGObjectAllocationSinkingPhase.cpp: - * dfg/DFGOpInfo.h: - (JSC::DFG::OpInfo::OpInfo): - * dfg/DFGPlan.cpp: - (JSC::DFG::Plan::compileInThreadImpl): - (JSC::DFG::Plan::finalizeWithoutNotifyingCallback): - * dfg/DFGRegisteredStructure.h: Added. - (JSC::DFG::RegisteredStructure::get): - (JSC::DFG::RegisteredStructure::operator->): - (JSC::DFG::RegisteredStructure::operator==): - (JSC::DFG::RegisteredStructure::operator!=): - (JSC::DFG::RegisteredStructure::operator bool): - (JSC::DFG::RegisteredStructure::RegisteredStructure): - (JSC::DFG::RegisteredStructure::createPrivate): - * dfg/DFGRegisteredStructureSet.cpp: Added. - (JSC::DFG::RegisteredStructureSet::filter): - (JSC::DFG::RegisteredStructureSet::filterArrayModes): - (JSC::DFG::RegisteredStructureSet::speculationFromStructures): - (JSC::DFG::RegisteredStructureSet::arrayModesFromStructures): - (JSC::DFG::RegisteredStructureSet::validateReferences): - * dfg/DFGRegisteredStructureSet.h: Added. - (JSC::DFG::RegisteredStructureSet::RegisteredStructureSet): - (JSC::DFG::RegisteredStructureSet::onlyStructure): - (JSC::DFG::RegisteredStructureSet::toStructureSet): - * dfg/DFGSafeToExecute.h: - (JSC::DFG::safeToExecute): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::emitAllocateRawObject): - (JSC::DFG::SpeculativeJIT::emitGetCallee): - (JSC::DFG::SpeculativeJIT::silentFill): - (JSC::DFG::SpeculativeJIT::checkArray): - (JSC::DFG::SpeculativeJIT::compileGetByValOnString): - (JSC::DFG::SpeculativeJIT::compileFromCharCode): - (JSC::DFG::SpeculativeJIT::compileDoubleRep): - (JSC::DFG::compileClampDoubleToByte): - (JSC::DFG::SpeculativeJIT::compileMakeRope): - (JSC::DFG::SpeculativeJIT::compileArithRounding): - (JSC::DFG::SpeculativeJIT::compileNewFunctionCommon): - (JSC::DFG::SpeculativeJIT::compileNewFunction): - (JSC::DFG::SpeculativeJIT::compileCreateActivation): - (JSC::DFG::SpeculativeJIT::compileCreateDirectArguments): - (JSC::DFG::SpeculativeJIT::compileCreateScopedArguments): - (JSC::DFG::SpeculativeJIT::compileCreateClonedArguments): - (JSC::DFG::SpeculativeJIT::compileSpread): - (JSC::DFG::SpeculativeJIT::compileArraySlice): - (JSC::DFG::SpeculativeJIT::compileTypeOf): - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOnCell): - (JSC::DFG::SpeculativeJIT::compileNewTypedArray): - (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject): - (JSC::DFG::SpeculativeJIT::compileMaterializeNewObject): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::TrustedImmPtr::TrustedImmPtr): - (JSC::DFG::SpeculativeJIT::TrustedImmPtr::weakPointer): - (JSC::DFG::SpeculativeJIT::TrustedImmPtr::operator MacroAssembler::TrustedImmPtr): - (JSC::DFG::SpeculativeJIT::TrustedImmPtr::asIntptr): - (JSC::DFG::SpeculativeJIT::callOperation): - (JSC::DFG::SpeculativeJIT::emitAllocateDestructibleObject): - (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined): - (JSC::DFG::SpeculativeJIT::emitCall): - (JSC::DFG::SpeculativeJIT::fillSpeculateCell): - (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot): - (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch): - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined): - (JSC::DFG::SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined): - (JSC::DFG::SpeculativeJIT::emitCall): - (JSC::DFG::SpeculativeJIT::compileObjectOrOtherLogicalNot): - (JSC::DFG::SpeculativeJIT::emitObjectOrOtherBranch): - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): - * dfg/DFGStrengthReductionPhase.cpp: - (JSC::DFG::StrengthReductionPhase::handleNode): - * dfg/DFGStructureAbstractValue.cpp: - (JSC::DFG::StructureAbstractValue::assertIsRegistered): - (JSC::DFG::StructureAbstractValue::clobber): - (JSC::DFG::StructureAbstractValue::observeTransition): - (JSC::DFG::StructureAbstractValue::observeTransitions): - (JSC::DFG::StructureAbstractValue::add): - (JSC::DFG::StructureAbstractValue::merge): - (JSC::DFG::StructureAbstractValue::mergeNotTop): - (JSC::DFG::StructureAbstractValue::filter): - (JSC::DFG::StructureAbstractValue::filterSlow): - (JSC::DFG::StructureAbstractValue::filterClassInfoSlow): - (JSC::DFG::StructureAbstractValue::contains): - (JSC::DFG::StructureAbstractValue::isSubsetOf): - (JSC::DFG::StructureAbstractValue::isSupersetOf): - (JSC::DFG::StructureAbstractValue::overlaps): - (JSC::DFG::StructureAbstractValue::isSubClassOf): - (JSC::DFG::StructureAbstractValue::dumpInContext): - * dfg/DFGStructureAbstractValue.h: - (JSC::DFG::StructureAbstractValue::StructureAbstractValue): - (JSC::DFG::StructureAbstractValue::operator=): - (JSC::DFG::StructureAbstractValue::set): - (JSC::DFG::StructureAbstractValue::toStructureSet): - (JSC::DFG::StructureAbstractValue::at): - (JSC::DFG::StructureAbstractValue::operator[]): - (JSC::DFG::StructureAbstractValue::onlyStructure): - * dfg/DFGStructureRegistrationPhase.cpp: - (JSC::DFG::StructureRegistrationPhase::StructureRegistrationPhase): Deleted. - (JSC::DFG::StructureRegistrationPhase::run): Deleted. - (JSC::DFG::StructureRegistrationPhase::registerStructures): Deleted. - (JSC::DFG::StructureRegistrationPhase::registerStructure): Deleted. - (JSC::DFG::StructureRegistrationPhase::assertAreRegistered): Deleted. - (JSC::DFG::StructureRegistrationPhase::assertIsRegistered): Deleted. - (JSC::DFG::performStructureRegistration): Deleted. - * dfg/DFGStructureRegistrationPhase.h: - * dfg/DFGTransition.cpp: - (JSC::DFG::Transition::dumpInContext): - * dfg/DFGTransition.h: - (JSC::DFG::Transition::Transition): - * dfg/DFGTypeCheckHoistingPhase.cpp: - (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheck): - (JSC::DFG::TypeCheckHoistingPhase::noticeStructureCheckAccountingForArrayMode): - * dfg/DFGValidate.cpp: - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::lower): - (JSC::FTL::DFG::LowerDFGToB3::compileCallObjectConstructor): - (JSC::FTL::DFG::LowerDFGToB3::compileCheckStructure): - (JSC::FTL::DFG::LowerDFGToB3::compilePutStructure): - (JSC::FTL::DFG::LowerDFGToB3::compileArraySlice): - (JSC::FTL::DFG::LowerDFGToB3::compileCreateActivation): - (JSC::FTL::DFG::LowerDFGToB3::compileNewFunction): - (JSC::FTL::DFG::LowerDFGToB3::compileCreateDirectArguments): - (JSC::FTL::DFG::LowerDFGToB3::compileCreateRest): - (JSC::FTL::DFG::LowerDFGToB3::compileNewArray): - (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSpread): - (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayBuffer): - (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize): - (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): - (JSC::FTL::DFG::LowerDFGToB3::compileAllocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::compileReallocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::compileMultiGetByOffset): - (JSC::FTL::DFG::LowerDFGToB3::compileMultiPutByOffset): - (JSC::FTL::DFG::LowerDFGToB3::compileGetMapBucket): - (JSC::FTL::DFG::LowerDFGToB3::compileOverridesHasInstance): - (JSC::FTL::DFG::LowerDFGToB3::compileCheckStructureImmediate): - (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): - (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeCreateActivation): - (JSC::FTL::DFG::LowerDFGToB3::compileNewRegexp): - (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenTail): - (JSC::FTL::DFG::LowerDFGToB3::checkStructure): - (JSC::FTL::DFG::LowerDFGToB3::checkInferredType): - (JSC::FTL::DFG::LowerDFGToB3::allocateObject): - (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject): - (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray): - (JSC::FTL::DFG::LowerDFGToB3::allocateUninitializedContiguousJSArray): - (JSC::FTL::DFG::LowerDFGToB3::boolify): - (JSC::FTL::DFG::LowerDFGToB3::equalNullOrUndefined): - (JSC::FTL::DFG::LowerDFGToB3::lowCell): - (JSC::FTL::DFG::LowerDFGToB3::speculateStringObjectForStructureID): - (JSC::FTL::DFG::LowerDFGToB3::weakPointer): - (JSC::FTL::DFG::LowerDFGToB3::frozenPointer): - (JSC::FTL::DFG::LowerDFGToB3::weakStructureID): - (JSC::FTL::DFG::LowerDFGToB3::weakStructure): - (JSC::FTL::DFG::LowerDFGToB3::crash): - * ftl/FTLOutput.h: - (JSC::FTL::Output::weakPointer): - (JSC::FTL::Output::constIntPtr): -2017-01-27 Matthew Hanson +2017-07-22 Jason Marcell - Merge r211246. rdar://problem/29916672 + Cherry-pick r219633. rdar://problem/33465535 - 2017-01-26 Mark Lam + 2017-07-18 Saam Barati - Fix missing exception check in genericTypedArrayViewProtoFuncSet(). - https://bugs.webkit.org/show_bug.cgi?id=166812 - - - Reviewed by Saam Barati. - - * runtime/JSGenericTypedArrayViewPrototypeFunctions.h: - (JSC::genericTypedArrayViewProtoFuncSet): - -2017-01-26 Matthew Hanson - - Merge r211224. rdar://problem/29144126 - - 2017-01-26 JF Bastien - - OSR entry: delay outer-loop compilation when at inner-loop - https://bugs.webkit.org/show_bug.cgi?id=167149 + AirLowerAfterRegAlloc may incorrectly use a callee save that's live as a scratch register + https://bugs.webkit.org/show_bug.cgi?id=174515 + Reviewed by Filip Pizlo. - As of https://bugs.webkit.org/show_bug.cgi?id=155217 OSR - compilation can be kicked off for an entry into an outer-loop, - while executing an inner-loop. This is desirable because often the - codegen from an inner-entry isn't as good as the codegen from an - outer-entry, but execution from an inner-loop is often pretty hot - and likely to kick off compilation. This approach provided nice - speedups on Kraken because we'd select to enter to the outer-loop - very reliably, which reduces variability (the inner-loop was - selected roughly 1/5 times from my unscientific measurements). + AirLowerAfterRegAlloc was computing the set of available scratch + registers incorrectly. It was always excluding callee save registers + from the set of live registers. It did not guarantee that live callee save + registers were not in the set of scratch registers that could + get clobbered. That's incorrect as the shuffling code is free + to overwrite whatever is in the scratch register it gets passed. - When compilation starts we take a snapshot of the JSValues at the - current execution state using OSR's recovery mechanism. These - values are passed to the compiler and are used as way to perform - type profiling, and could be used to observe cell types as well as - to perform predictions such as through constant propagation. + * b3/air/AirLowerAfterRegAlloc.cpp: + (JSC::B3::Air::lowerAfterRegAlloc): + * b3/testb3.cpp: + (JSC::B3::functionNineArgs): + (JSC::B3::testShuffleDoesntTrashCalleeSaves): + (JSC::B3::run): + * jit/RegisterSet.h: - It's therefore desired to enter from the outer-loop when we can, - but we need to be executing from that location to capture the - right JSValues, otherwise we're confusing the compiler and giving - it inaccurate JSValues which can lead it to predict the wrong - things, leading to suboptimal code or recompilation due to - misprediction, or in super-corner-cases a crash. +2017-07-17 Jason Marcell - These effects are pretty hard to measure: Fil points out that - marsalis-osr-entry really needs mustHandleValues (the JSValues - from the point of execution) because right now it just happens to - correctly guess int32. I tried removing mustHandleValues entirely - and saw no slowdowns, but our benchmarks probably aren't - sufficient to reliably find issues, sometimes because we happen to - have sufficient mitigations. + Cherry-pick r219413. rdar://problem/33337335 - DFG tier-up was added here: - https://bugs.webkit.org/show_bug.cgi?id=112838 + 2017-06-29 Dean Jackson - * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGJITCode.h: - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::JITCompiler): - * dfg/DFGOSREntry.cpp: - (JSC::DFG::prepareOSREntry): - * dfg/DFGOSREntry.h: - (JSC::DFG::prepareOSREntry): - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGTierUpEntryTrigger.h: Copied from Source/JavaScriptCore/ftl/FTLOSREntry.h. - * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.cpp: - (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::ToFTLForOSREntryDeferredCompilationCallback): - (JSC::DFG::RefToFTLForOSREntryDeferredCompilationCallback::create): - (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidBecomeReadyAsynchronously): - (JSC::DFG::ToFTLForOSREntryDeferredCompilationCallback::compilationDidComplete): - * dfg/DFGToFTLForOSREntryDeferredCompilationCallback.h: - * ftl/FTLOSREntry.cpp: - (JSC::FTL::prepareOSREntry): - * ftl/FTLOSREntry.h: - * jit/JITOperations.cpp: - -2017-01-26 Matthew Hanson - - Merge r211167. rdar://problem/30192652 - - 2017-01-25 Filip Pizlo - - ARM/ARM64 stress/atomics-store-return.js fails - - - Reviewed by Michael Saboff. - - The problem was relying on double->int casts for anything. We need to use toInt32(). - - * runtime/AtomicsObject.cpp: - (JSC::atomicsFuncCompareExchange): - (JSC::atomicsFuncExchange): - (JSC::atomicsFuncStore): - -2017-01-26 Matthew Hanson - - Merge r211180. rdar://problem/30156092 - - 2017-01-25 Matthew Hanson - - Merge r211124. rdar://problem/30156092 - - 2017-01-24 Michael Saboff - - InferredTypeTable entry manipulation is not TOCTOU race safe - https://bugs.webkit.org/show_bug.cgi?id=167344 - - Reviewed by Filip Pizlo. - - Made the accesses to table values safe from Time of Check, - Time of Use races with local temporary values. - - Fixed point that we set an entry in the table to access the - current table entry instead of using the local entry. In that case, - we reload the now changed entry. - - * runtime/InferredTypeTable.cpp: - (JSC::InferredTypeTable::visitChildren): - (JSC::InferredTypeTable::get): - (JSC::InferredTypeTable::willStoreValue): - (JSC::InferredTypeTable::makeTop): - -2017-01-25 Matthew Hanson - - Rollout r211180. - -2017-01-25 Matthew Hanson - - Merge r211129. rdar://problem/30178458 - - 2017-01-24 Filip Pizlo - - Atomics.store should return the int-converted value according to toInteger - https://bugs.webkit.org/show_bug.cgi?id=167399 - - Reviewed by Saam Barati. - - I keep getting this wrong, but I think I've finally done it right. What we want is for - Atomics.store to return the value it was passed after toInteger, which doesn't clip the value to - any kind of range. It does get truncated to double. - - This changes the code to pass those "integers" as doubles. It doesn't matter that this is slow, - since all of these code paths are slow due to their need to check everything. We'll take care of - that by making them intrinsic later. - - * runtime/AtomicsObject.cpp: - (JSC::atomicsFuncAdd): - (JSC::atomicsFuncAnd): - (JSC::atomicsFuncCompareExchange): - (JSC::atomicsFuncExchange): - (JSC::atomicsFuncLoad): - (JSC::atomicsFuncOr): - (JSC::atomicsFuncStore): - (JSC::atomicsFuncSub): - (JSC::atomicsFuncXor): - -2017-01-25 Matthew Hanson - - Merge r211122. rdar://problem/30177808 - - 2017-01-24 Filip Pizlo - - Atomics.store should return the int-converted value, not the value that it stored - https://bugs.webkit.org/show_bug.cgi?id=167395 - - Reviewed by Saam Barati. - - Previously the code was based around passing a lambda that operated over the native type of the - operation (so for example int8_t if we were doing things to Int8Arrays). But to support this - behavior of store, we need it to be able to control how it converts its result to JSValue and it - needs to see its argument as an int32_t. It turns out that it's easy for all of the functions in - AtomicsObject.cpp to also adopt this protocol since the conversion to JSValue is just jsNumber() - from the native type in those cases, and the conversion from int32_t is done for free in - std::atomic. - - * runtime/AtomicsObject.cpp: - (JSC::atomicsFuncAdd): - (JSC::atomicsFuncAnd): - (JSC::atomicsFuncCompareExchange): - (JSC::atomicsFuncExchange): - (JSC::atomicsFuncLoad): - (JSC::atomicsFuncOr): - (JSC::atomicsFuncStore): - (JSC::atomicsFuncSub): - (JSC::atomicsFuncXor): - -2017-01-25 Matthew Hanson - - Merge r211113. rdar://problem/30174692 - - 2017-01-24 Filip Pizlo - - -0 is a valid array index and AtomicsObject should know this - https://bugs.webkit.org/show_bug.cgi?id=167386 - - Reviewed by Mark Lam. - - * runtime/AtomicsObject.cpp: The bug title really says it all. - -2017-01-25 Matthew Hanson - - Merge r211111. rdar://problem/30173375 - - 2017-01-24 Filip Pizlo - - Enable the stochastic space-time scheduler on the larger multicores - https://bugs.webkit.org/show_bug.cgi?id=167382 - - - Rubber stamped by Saam Barati - - This looks like a 1.3% JetStream speed-up thanks to a 28% splay-latency improvement. This new - scheduler seems to prevent all of the same pathologies as the old one prevented. But instead of - periodically suspending the mutator, this new one will only suspend after an iteration of the - constraint fixpoint. The length of that suspension length is random with the distribution being - governed by mutatorUtilization. Once resumed, the mutator gets to run unimpeded until draining - stalls. - - I'm enabling it on platforms as I benchmark those platforms. It's possible that we will want to - use a different scheduler on different platforms. - - * runtime/Options.cpp: - (JSC::overrideDefaults): - -2017-01-25 Matthew Hanson - - Merge r211124. rdar://problem/30156092 - - 2017-01-24 Michael Saboff - - InferredTypeTable entry manipulation is not TOCTOU race safe - https://bugs.webkit.org/show_bug.cgi?id=167344 - - Reviewed by Filip Pizlo. - - Made the accesses to table values safe from Time of Check, - Time of Use races with local temporary values. - - Fixed point that we set an entry in the table to access the - current table entry instead of using the local entry. In that case, - we reload the now changed entry. - - * runtime/InferredTypeTable.cpp: - (JSC::InferredTypeTable::visitChildren): - (JSC::InferredTypeTable::get): - (JSC::InferredTypeTable::willStoreValue): - (JSC::InferredTypeTable::makeTop): - -2017-01-25 Dean Jackson - - Disable Variation fonts on this branch. - - - * Configurations/FeatureDefines.xcconfig: - -2017-01-24 Matthew Hanson - - Merge r211070. rdar://problem/30121809 - - 2017-01-23 Saam Barati - - https://bugs.webkit.org/show_bug.cgi?id=167247 - JSC: operationSpreadGeneric uses the wrong global object for the builtin function and slow_path_spread consults the wrong global object to prove if the iterator protocol is unobservable - - - Reviewed by Filip Pizlo. - - There were two bugs in the different tiers with respect to how - spread handled global objects. - - The first was in the LLInt/baseline inside slow_path_spread: - - We consulted the lexical global object instead of the thing we're - spreading's global object to determine if the array iterator protocol - is unobservable. This is wrong if the incoming array is from a different - global object. We must consult the incoming array's global object - to determine if it can be spread using the fast path. - - The second was in operationSpreadGeneric in the DFG/FTL: - - We were always using the incoming array's global object, even - when going down the slow path. This is wrong because we were - fetching the builtin iteration function helper from the incoming - array's global object, which meant that if the iterator function - were to throw an exception, it could leak objects from a different - global object. We should be executing the iterator function with - the lexical global object. - - * dfg/DFGOperations.cpp: - * jsc.cpp: - (GlobalObject::finishCreation): - (functionGlobalObjectForObject): - * runtime/CommonSlowPaths.cpp: - (JSC::SLOW_PATH_DECL): - * runtime/JSArray.h: - * runtime/JSArrayInlines.h: - (JSC::JSArray::isIteratorProtocolFastAndNonObservable): - -2017-01-24 Matthew Hanson - - Merge r211069. rdar://problem/30173274 - - 2017-01-22 Filip Pizlo - - Land the stochastic space-time scheduler disabled - https://bugs.webkit.org/show_bug.cgi?id=167249 - - Reviewed by Saam Barati. - - The space-time scheduler is pretty weird. It uses a periodic scheduler where the next period is - simply determined by an integer multiple of time since when the scheduler last snapped phase. It - snaps phase after constraint solving. Both the snapping of the phase after constraint solving and - the periodicity appear to be necessary for good performance. For example, if the space-time - scheduler decided that it was in the resume part of the phase just by virtue of having just - resumed, then it would be empirically worse than our scheduler which asks "what time is it?" to - decide whether it should be suspended or resumed even if it just suspended or resumed. I've spent - a lot of time wondering why these two features are essential, and I think I found a reason. - - What's happening is that sometimes the GC has an overrun and its increment takes longer than it - should have. The current scheduler forgives overruns when constraint solving, which seems to - make sense because it cannot control whether constraint solving runs with the mutator resumed or - suspended. It has to be suspended currently. Snapping phase after constraint solving accomplishes - this. What's more surprising is how important it is to manage deadline misses during draining. - The relevant kind of deadline miss is when doing mutator-suspended draining to catch up to the - retreating wavefront. Deadline misses while doing this can happen systematically in some - workloads, like JetStream/hash-map and some test in Speedometer. It's because they have some - ginormous object and it takes like ~3ms+-1.5ms just to scan it. The space-time scheduler's use - of time to decide what to do saves the day here: after the deadline miss, the scheduler will - initially realize that it missed its deadline to resume the mutator. But as soon as it does this - it asks: "based on current time since phase snap, what should I do?". In the case of a deadline - miss, this question is essentially a weighted coin flip because of the high noise in the amount - of time that it takes to do things in the GC. If you overrun, you will probably overrun by - multiple milliseconds, which is enough that where you land in the space-time scheduler's timeline - is random. The likelihood that you land in the "resume mutator" part of the timeline has a - probability that is roughly the same as what the space-time scheduler calls mutator utilization. - This is a super weird property. I did not intend for it to have this property, but it appears to - be the most important property of this scheduler. - - Based on this, it seems that the fact that the space-time scheduler could suspend the mutator - before draining runs out of work doesn't accomplish anything. As soon as you resume the - mutator, you have a retreating wavefront to worry about. But if the collector is happily scanning - things then it's almost certain that the collector will outpace the mutator. Also, anything that - the mutator asks us to revisit is deferred anyway. - - In the past I've tried to replace the scheduler in one patch and this turned out to be annoying - because even a poorly conceived scheduler should be iterated on. This patch lands a new scheduler - called the StochasticSpaceTime scheduler. It replaces two of the known-good features of the old - scheduler: (1) it forgives constraint pauses and (2) after deadline overrun its choice is random, - weighted by the mutator utilization target. Unlike the old scheduler, this one will only suspend - the mutator when the draining terminates, but it may pause for any amount of time after an - iteration of constraint solving. It computes the targetPause by measuring constraint solving time - and multiplying by the pauseScale (0.3 by default). If smaller then minimumPause (0.3ms by - default), then it uses minimumPause instead. The stochastic scheduler will then definitely do at - least targetPause worth of suspended draining after the constraint solving iteration, and then - it will decide whether or not to do another one at random. The probability that it will choose to - resume is exactly mutatorUtilization, which is computed exactly as before. Therefore, the - probability of resumption starts at 0.7 and goes down as memory usage rises. Conversely, the - probability that we will stay suspended starts at 0.3 and goes up from there. - - This new scheduler looks like it might be a 25% improvement on splay-latency. It also looks like - a small progression on hash-map. Hash-map is a great test of one of the worst cases of retreating - wavefront, since it is repeatedly storing to a ginormous array. This array is sure to take a - while to scan, and to complete, the GC must be smart enough to visit any new objects it finds - while scanning the array immediately after scanning that array. This new scheduler means that - after scanning the array, the probability that you will scan whatever you found in it starts at - 0.3 and rises as the program allocates. It's sure to be 0.3, and not 0.3^k, because after the - wavefront stops advancing, the only object on the mark stack after a constraint iteration will be - that array. Since there is sure to be a 0.3ms or longer pause, the GC will be sure to start - visiting this object. The GC can then complete if it just allows enough time after this to scan - whatever new objects it finds. If scanning the array overruns the deadline (and it almost - certainly will) then the probability that the GC keeps the mutator suspended is simply - 1 - mutatorUtilization. - - This scheduler is disabled by default. You can enable it with - --useStochasticMutatorScheduler=true. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::markToFixpoint): - * heap/Heap.h: - * heap/MarkingConstraintSet.cpp: - (JSC::MarkingConstraintSet::didStartMarking): - (JSC::MarkingConstraintSet::executeConvergenceImpl): - (JSC::MarkingConstraintSet::resetStats): Deleted. - (JSC::MarkingConstraintSet::executeBootstrap): Deleted. - * heap/MarkingConstraintSet.h: - * heap/MutatorScheduler.cpp: - (JSC::MutatorScheduler::didReachTermination): - (JSC::MutatorScheduler::synchronousDrainingDidStall): - * heap/MutatorScheduler.h: - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::didReachTermination): - (JSC::SlotVisitor::drainFromShared): - * heap/StochasticSpaceTimeMutatorScheduler.cpp: Added. - (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::Snapshot): - (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::now): - (JSC::StochasticSpaceTimeMutatorScheduler::Snapshot::bytesAllocatedThisCycle): - (JSC::StochasticSpaceTimeMutatorScheduler::StochasticSpaceTimeMutatorScheduler): - (JSC::StochasticSpaceTimeMutatorScheduler::~StochasticSpaceTimeMutatorScheduler): - (JSC::StochasticSpaceTimeMutatorScheduler::state): - (JSC::StochasticSpaceTimeMutatorScheduler::beginCollection): - (JSC::StochasticSpaceTimeMutatorScheduler::didStop): - (JSC::StochasticSpaceTimeMutatorScheduler::willResume): - (JSC::StochasticSpaceTimeMutatorScheduler::didReachTermination): - (JSC::StochasticSpaceTimeMutatorScheduler::didExecuteConstraints): - (JSC::StochasticSpaceTimeMutatorScheduler::synchronousDrainingDidStall): - (JSC::StochasticSpaceTimeMutatorScheduler::timeToStop): - (JSC::StochasticSpaceTimeMutatorScheduler::timeToResume): - (JSC::StochasticSpaceTimeMutatorScheduler::log): - (JSC::StochasticSpaceTimeMutatorScheduler::endCollection): - (JSC::StochasticSpaceTimeMutatorScheduler::setResumeTime): - (JSC::StochasticSpaceTimeMutatorScheduler::bytesAllocatedThisCycleImpl): - (JSC::StochasticSpaceTimeMutatorScheduler::bytesSinceBeginningOfCycle): - (JSC::StochasticSpaceTimeMutatorScheduler::maxHeadroom): - (JSC::StochasticSpaceTimeMutatorScheduler::headroomFullness): - (JSC::StochasticSpaceTimeMutatorScheduler::mutatorUtilization): - * heap/StochasticSpaceTimeMutatorScheduler.h: Added. - * runtime/Options.cpp: - (JSC::overrideDefaults): - * runtime/Options.h: - -2017-01-24 Matthew Hanson - - Merge r211065. rdar://problem/29784295 - - 2017-01-23 Filip Pizlo - - SharedArrayBuffer plus WebGL should not equal CRASH - https://bugs.webkit.org/show_bug.cgi?id=167329 - - Reviewed by Saam Barati. - - DOM unwrapping methods should return null rather than crashing. The code expects an - unshared buffer, so we should return null when it's shared. The caller can then decide - if they like null or not. - - * runtime/JSArrayBufferViewInlines.h: - (JSC::JSArrayBufferView::toWrapped): - -2017-01-24 Matthew Hanson - - Merge r211043. rdar://problem/30134434 - - 2017-01-23 Michael Saboff - - IntlObject uses JSArray::tryCreateUninitialized in an unsafe way - https://bugs.webkit.org/show_bug.cgi?id=167288 - - Reviewed by Filip Pizlo. - - Refactored the following "create" methods into a "tryCreate" method and a - "create" wrapper: JSArray::create(), Butterfly::create() and - createArrayButterfly(). - - Changed IntlObject.cpp to use JSArray::tryCreate() as it is simpler to use - by not requiring the caller to be GC savey. The performance benefits of - tryCreateUninitialized() are not needed by the IntlObject c++ code. - - Did not add a new test as the bug caused LayoutTests/js/intl.html to fail - reliably with the JSC option values scribbleFreeCells=true, - collectContinuously=true and JSC_useGenerationalGC=false. - - * runtime/Butterfly.h: - * runtime/ButterflyInlines.h: - (JSC::Butterfly::tryCreate): Added. - (JSC::Butterfly::create): - * runtime/IntlObject.cpp: - (JSC::canonicalizeLocaleList): - (JSC::lookupSupportedLocales): - (JSC::intlObjectFuncGetCanonicalLocales): - * runtime/JSArray.h: - (JSC::createContiguousArrayButterfly): Deleted. - (JSC::tryCreateArrayButterfly): Added. - (JSC::createArrayButterfly): - (JSC::JSArray::tryCreate): Added. - (JSC::JSArray::create): - -2017-01-24 Matthew Hanson - - Merge r210971. rdar://problem/30115838 - - 2017-01-20 Saam Barati - - We should flash a safepoint before each DFG/FTL phase - https://bugs.webkit.org/show_bug.cgi?id=167234 - - Reviewed by Filip Pizlo. - - The recent GC changes caused us to regress Kraken because of a - longstanding issue that happened to be hit with higher frequency because - of a change in timing between when a particular GC was happening and - when a particular FTL compilation was happening. The regression is caused - by the GC was waiting for a large function to make it through the DFG portion - of an FTL compilation. This was taking 20ms-30ms and started happened during a - particular test with much higher frequency. - - This means that anytime the GC waits for this compilation, the test ran at least - ~20ms slower because the GC waits for the compiler threads the mutator is stopped. - - It's good that we have such an easily reproducible case of this performance - issue because it will effect many real JS programs, especially ones with - large functions that get hot. - - The most straight forward solution to fix this is to flash a safepoint before - each phase, allowing the GC to suspend the compiler if needed. In my testing, - this progresses Kraken in the browser, and doesn't regress anything else. This - solution also makes the most sense. I did some analysis on the compilation time - of this function that took ~20-30ms to pass through the DFG phases, and - the phase times were mostly evenly distributed. Some took longer than others, - but no phase was longer than 3ms. Most were in the 0.25ms to 1.5ms range. - - * dfg/DFGPlan.cpp: - (JSC::DFG::Plan::compileInThreadImpl): - * dfg/DFGSafepoint.cpp: - (JSC::DFG::Safepoint::begin): - * runtime/Options.h: - -2017-01-20 Matthew Hanson - - Merge r210949. rdar://problem/30108531 - - 2017-01-19 Chris Dumez - - iterable<> should be enabled on WK1 - https://bugs.webkit.org/show_bug.cgi?id=167221 - - - Reviewed by Youenn Fablet. - - * runtime/CommonIdentifiers.h: - -2017-01-20 Matthew Hanson - - Merge r210947. rdar://problem/30108809 - - 2017-01-19 Filip Pizlo - - Structure::pin() needs to be called while holding a lock - https://bugs.webkit.org/show_bug.cgi?id=167220 - - Reviewed by Saam Barati. - - Imagine this race: the mutator calls pin() and the collector calls visitChildren(), - on the same Structure at the same time. In trunk pin() does not require a lock to be - held and it doesn't grab any locks. Meanwhile visitChildren() grabs the lock, checks - if the structure is pinned, and if not, it removes it by overwriting with zero. Now - imagine how this plays out when pin() runs. Since pin() grabs no locks, it is - irrelevant that visitChildren() grabs any locks. So, visitChildren() might check if - the table is pinned before pin() pins it, and then clear the table after it was - already pinned. - - The problem here is that pin() should be holding a lock. We could either make pin() - grab that lock by itself, or what this patch does is makes the caller grab the lock. - This is great because it means that sometimes we don't have to introduce any new - locking. - - This fixes a materializePropertyTable() checkOffsetConsistency() crash that happens - very rarely, but I was able to get it to reproduce with run-webkit-tests and - aggressive GC settings. - - * runtime/ConcurrentJSLock.h: - * runtime/Structure.cpp: - (JSC::Structure::materializePropertyTable): - (JSC::Structure::changePrototypeTransition): - (JSC::Structure::attributeChangeTransition): - (JSC::Structure::toDictionaryTransition): - (JSC::Structure::nonPropertyTransition): - (JSC::Structure::pin): - (JSC::Structure::pinForCaching): - (JSC::Structure::add): - * runtime/Structure.h: - * runtime/StructureInlines.h: - (JSC::Structure::checkOffsetConsistency): - (JSC::Structure::add): - (JSC::Structure::addPropertyWithoutTransition): - -2017-01-20 Matthew Hanson - - Merge r210935. rdar://problem/30101860 - - 2017-01-19 Filip Pizlo - - The mutator needs to fire a barrier after memmoving stuff around in an object that the GC scans - https://bugs.webkit.org/show_bug.cgi?id=167208 - - Reviewed by Saam Barati. - - It used to be that if you moved a value from one place to another in the same object - then there is no need for a barrier because the generational GC would have no need to - know that some old object still continues to refer to the same other old object. - - But the concurrent GC might scan that object as the mutator moves pointers around in - it. If the ordering is right, this could mean that the collector never sees some of - those pointers. This can be fixed by adding a barrier. - - This fixes the most obvious cases I found. There may be more and I'll continue to - audit. Most of the other memmove users seem to already use some kind of synchronization - to prevent this. For example, this can also be fixed by just holding the cell lock - around the memmove since we're dealing with indexing storage and the GC reads that - under the cell lock. - - * runtime/JSArray.cpp: - (JSC::JSArray::shiftCountWithAnyIndexingType): - (JSC::JSArray::unshiftCountWithAnyIndexingType): - -2017-01-18 Matthew Hanson - - Merge r210858. rdar://problem/30069096 - - 2017-01-18 Filip Pizlo - - JSObjectSetPrivate should not use jsCast<> - rdar://problem/30069096 - - Reviewed by Keith Miller. - - * API/JSObjectRef.cpp: - (JSObjectSetPrivate): - -2017-01-18 Matthew Hanson - - Merge r210844. rdar://problem/29993906 - - 2017-01-16 Filip Pizlo - - Make opaque root scanning truly constraint-based - https://bugs.webkit.org/show_bug.cgi?id=165760 - - Reviewed by Geoffrey Garen. - - We have bugs when visitChildren() changes its mind about what opaque root to add, since - we don't have barriers on opaque roots. This supposedly once worked for generational GC, - and I started adding more barriers to support concurrent GC. But I think that the real - bug here is that we want the JSObject->OpaqueRoot to be evaluated as a constraint that - participates in the fixpoint. I like to think of this as an *output* constraint, because it - is concerned with outgoing edges in the heap from the object that registered the constraint. - An *input* constraint is like what Weak<> does when deciding whether the thing it points to - should be live. - - Whether or not an object has output constraints depends on its type. So, we want the GC to - have a feature where we rapidly call some function on all marked objects of some type. - - It's easy to rapidly scan all marked objects in a MarkedBlock. So, we want to allocate all - objects that have output constraints in their own MarkedBlocks and we want to track the set - of MarkedBlocks with output constraints. - - This patch makes it easy to have clients of JSC's internal C++ APIs create a Subspace - like - what we used to call MarkedSpace::Subspace but now it's in the JSC namespace - which is - a collection of objects that you can easily scan during GC from a MarkingConstraint. It's - now possible for internal C++ API clients to register their own MarkingConstraints. The DOM - now uses this to create two Subspaces (more on why two below) and it calls - JSCell::visitOutputConstraints() on all of the marked objects in those subspaces using a new - MarkingConstraint. That MarkingConstraint uses a new style of volatility, called - SeldomGreyed, which is like GreyedByExecution except it is opportunistically not executed - as roots in the hopes that their sole execution will be the snapshot-at-the-end. I also - converted the CodeBlock rescan constraint to SeldomGreyed, since that's also an output - constraint. - - This patch also uses Subspace for something pretty obvious: knowing how to call the - destructor. Subspaces can specialize the sweep for their way of invoking destructors. We - have the following subspaces: - - - auxiliary - - cell - - destructibleCell - for JSCell subclasses that have destructors and StructureIsImmortal - - stringSpace - inlines ~JSString into the sweep, making string allocation 7% faster - - destructibleObjectSpace - for JSDestructibleObject subclasses - - And WebCore adds: - - - outputConstraint - for JSDOMObjects that have a visitAdditionalChildren - - globalObjectOutputConstraint - for JSDOMGlobalObjects that have a visitAdditionalChildren, - since JSDOMGlobalObjects are not JSDestructibleObjects - - The Subspace for a type is selected by saying JSC::subspaceFor(vm). This calls - Type::subspaceFor(vm). This allows cell classes to override subspaceFor<> and it - allows any subspaceFor<> implementation to query static flags in the type. This is how - JSCell::subspaceFor<> can select either cellSpace or destructibleCellSpace. - - This patch is mostly about: - - - Moving MarkedSpace::Subspace out of MarkedSpace and making it a nice class with a nice - API. Almost all of its functionality is just taken out of MarkedSpace. - - Converting users of the old API for allocating objects and getting MarkedAllocators, like - heap.allocatorForObjectWithoutDestructor() and its friends. That would now say - vm.cellSpace.allocatorFor(). - - Altogether, this means that we only have a small regression on Dromaeo. The regression is - due to the fact that we scan output constraints. Before the Subspace optimizations (see - r209766, which was rolled out in r209812), this regression on Dromaeo/jslib was 2x but after - the optimizations in this patch it's only 1.12x. Note that Dromaeo/jslib creats gigabytes of - DOM nodes. Compared to web pages, this is a very extreme synthetic microbenchmark. Still, we - like optimizing these because we don't want to presume what web pages will look like. - - The use of Subspaces to specialize destructors happened not because it's super necessary but - because I wanted to introduce a single unified way of communicating to the GC how to treat - different types. Any Subspace feature that allowed us to collect some types together would - have to be mindful of the destructorness of objects. I could have turned this into a - liability where each Subspace has two subsubspaces - one for destructor objects and one for - non-destructor objects, which would have allowed me to keep the old sweep specialization - code. Just days prior, mlam wanted to do something that was hard because of that old sweep - specializer, so I decided to take the opportunity to fix the sweep specializer while also - making Subspace be the one true way of teaching the GC about types. To validate that this - actually does things, I added a JSStringSubspace and a test that shows that this is a 7% - string allocation progression. - - In bug 167066, I'm getting rid of the rest of the code in JSC that would special-case for - JSDestructibleObject vs StructureIsImmortal by using the GC's DestructionMode. After that, - Subspace will be only mechanism by which JSC uses the GC to encode types. - - Prior to this change, having multiple MarkedSpace::Subspaces would have been expensive - because they create a bunch of MarkedAllocators upfront. We now have the ability to create - MarkedAllocators lazily. We create them on the first allocation from that size class or when - a JIT asks for the MarkedAllocator. The concurrent JITs can ask for MarkedAllocators because - their creation is under a lock. - - On my machine, this might be a 1.1% JetStream speed-up with 87% confidence and it might be - a 0.4% PLT3 slow-down with 92% confidence. Note that 0.4% on PLT3 is the level of systematic - error on PLT3 on my computer: I've seen definite 0.4% speed-ups and slow-downs that were not - confirmed by any bot. Let's see what the bots say. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/ObjectAllocationProfile.h: - (JSC::ObjectAllocationProfile::initialize): - * bytecode/PolymorphicAccess.cpp: - (JSC::AccessCase::generateImpl): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::emitAllocateRawObject): - (JSC::DFG::SpeculativeJIT::compileMakeRope): - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileNewTypedArray): - (JSC::DFG::SpeculativeJIT::emitAllocateButterfly): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * ftl/FTLAbstractHeapRepository.h: - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): - (JSC::FTL::DFG::LowerDFGToB3::compileMakeRope): - (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): - (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl): - (JSC::FTL::DFG::LowerDFGToB3::allocateObject): - (JSC::FTL::DFG::LowerDFGToB3::allocatorForSize): - (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedObject): - (JSC::FTL::DFG::LowerDFGToB3::allocateVariableSizedCell): - (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray): - * heap/AllocatorAttributes.h: - (JSC::AllocatorAttributes::AllocatorAttributes): - * heap/ConstraintVolatility.h: Added. - (WTF::printInternal): - * heap/GCActivityCallback.cpp: - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::lastChanceToFinalize): - (JSC::Heap::markToFixpoint): - (JSC::Heap::updateObjectCounts): - (JSC::Heap::collectAllGarbage): - (JSC::Heap::collectInThread): - (JSC::Heap::stopTheWorld): - (JSC::Heap::updateAllocationLimits): - (JSC::Heap::bytesVisited): - (JSC::Heap::addCoreConstraints): - (JSC::Heap::addMarkingConstraint): - (JSC::Heap::notifyIsSafeToCollect): - (JSC::Heap::preventCollection): - (JSC::Heap::allowCollection): - (JSC::Heap::setMutatorShouldBeFenced): - (JSC::Heap::buildConstraintSet): Deleted. - (JSC::Heap::writeBarrierOpaqueRootSlow): Deleted. - (JSC::Heap::addMutatorShouldBeFencedCache): Deleted. - * heap/Heap.h: - (JSC::Heap::mutatorExecutionVersion): - (JSC::Heap::numOpaqueRoots): - (JSC::Heap::vm): Deleted. - (JSC::Heap::subspaceForObjectWithoutDestructor): Deleted. - (JSC::Heap::subspaceForObjectDestructor): Deleted. - (JSC::Heap::subspaceForAuxiliaryData): Deleted. - (JSC::Heap::allocatorForObjectWithoutDestructor): Deleted. - (JSC::Heap::allocatorForObjectWithDestructor): Deleted. - (JSC::Heap::allocatorForAuxiliaryData): Deleted. - * heap/HeapInlines.h: - (JSC::Heap::vm): - (JSC::Heap::allocateWithDestructor): Deleted. - (JSC::Heap::allocateWithoutDestructor): Deleted. - (JSC::Heap::allocateObjectOfType): Deleted. - (JSC::Heap::subspaceForObjectOfType): Deleted. - (JSC::Heap::allocatorForObjectOfType): Deleted. - (JSC::Heap::allocateAuxiliary): Deleted. - (JSC::Heap::tryAllocateAuxiliary): Deleted. - (JSC::Heap::tryReallocateAuxiliary): Deleted. - (JSC::Heap::ascribeOwner): Deleted. - (JSC::Heap::writeBarrierOpaqueRoot): Deleted. - * heap/LargeAllocation.cpp: - (JSC::LargeAllocation::tryCreate): - (JSC::LargeAllocation::LargeAllocation): - (JSC::LargeAllocation::~LargeAllocation): - (JSC::LargeAllocation::sweep): - * heap/LargeAllocation.h: - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::MarkedAllocator): - (JSC::MarkedAllocator::tryAllocateWithoutCollecting): - (JSC::MarkedAllocator::tryAllocateIn): - (JSC::MarkedAllocator::allocateSlowCaseImpl): - (JSC::MarkedAllocator::tryAllocateBlock): - (JSC::MarkedAllocator::shrink): - (JSC::MarkedAllocator::markedSpace): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::nextAllocatorInSubspace): - (JSC::MarkedAllocator::setNextAllocatorInSubspace): - (JSC::MarkedAllocator::subspace): - (JSC::MarkedAllocator::tryAllocate): Deleted. - (JSC::MarkedAllocator::allocate): Deleted. - (JSC::MarkedAllocator::forEachBlock): Deleted. - * heap/MarkedAllocatorInlines.h: Added. - (JSC::MarkedAllocator::tryAllocate): - (JSC::MarkedAllocator::allocate): - (JSC::MarkedAllocator::forEachBlock): - (JSC::MarkedAllocator::forEachNotEmptyBlock): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::Handle::subspace): - (JSC::MarkedBlock::Handle::sweep): - (JSC::MarkedBlock::Handle::specializedSweep): Deleted. - (JSC::MarkedBlock::Handle::sweepHelperSelectScribbleMode): Deleted. - (JSC::MarkedBlock::Handle::sweepHelperSelectEmptyMode): Deleted. - (JSC::MarkedBlock::Handle::sweepHelperSelectHasNewlyAllocated): Deleted. - (JSC::MarkedBlock::Handle::sweepHelperSelectSweepMode): Deleted. - (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): Deleted. - * heap/MarkedBlock.h: - (JSC::MarkedBlock::Handle::visitWeakSet): - * heap/MarkedBlockInlines.h: - (JSC::MarkedBlock::Handle::isNewlyAllocatedStale): - (JSC::MarkedBlock::Handle::hasAnyNewlyAllocated): - (JSC::MarkedBlock::heap): - (JSC::MarkedBlock::space): - (JSC::MarkedBlock::Handle::space): - (JSC::MarkedBlock::Handle::specializedSweep): - (JSC::MarkedBlock::Handle::finishSweepKnowingSubspace): - (JSC::MarkedBlock::Handle::sweepDestructionMode): - (JSC::MarkedBlock::Handle::emptyMode): - (JSC::MarkedBlock::Handle::scribbleMode): - (JSC::MarkedBlock::Handle::newlyAllocatedMode): - (JSC::MarkedBlock::Handle::marksMode): - (JSC::MarkedBlock::Handle::forEachMarkedCell): - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::initializeSizeClassForStepSize): - (JSC::MarkedSpace::MarkedSpace): - (JSC::MarkedSpace::lastChanceToFinalize): - (JSC::MarkedSpace::addMarkedAllocator): - (JSC::MarkedSpace::allocate): Deleted. - (JSC::MarkedSpace::tryAllocate): Deleted. - (JSC::MarkedSpace::allocateLarge): Deleted. - (JSC::MarkedSpace::tryAllocateLarge): Deleted. - * heap/MarkedSpace.h: - (JSC::MarkedSpace::heap): - (JSC::MarkedSpace::allocatorLock): - (JSC::MarkedSpace::subspaceForObjectsWithDestructor): Deleted. - (JSC::MarkedSpace::subspaceForObjectsWithoutDestructor): Deleted. - (JSC::MarkedSpace::subspaceForAuxiliaryData): Deleted. - (JSC::MarkedSpace::allocatorFor): Deleted. - (JSC::MarkedSpace::destructorAllocatorFor): Deleted. - (JSC::MarkedSpace::auxiliaryAllocatorFor): Deleted. - (JSC::MarkedSpace::allocateWithoutDestructor): Deleted. - (JSC::MarkedSpace::allocateWithDestructor): Deleted. - (JSC::MarkedSpace::allocateAuxiliary): Deleted. - (JSC::MarkedSpace::tryAllocateAuxiliary): Deleted. - (JSC::MarkedSpace::forEachSubspace): Deleted. - * heap/MarkingConstraint.cpp: - (JSC::MarkingConstraint::MarkingConstraint): - * heap/MarkingConstraint.h: - (JSC::MarkingConstraint::volatility): - * heap/MarkingConstraintSet.cpp: - (JSC::MarkingConstraintSet::resetStats): - (JSC::MarkingConstraintSet::add): - (JSC::MarkingConstraintSet::executeConvergenceImpl): - * heap/MarkingConstraintSet.h: - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::visitChildren): - (JSC::SlotVisitor::visitAsConstraint): - (JSC::SlotVisitor::drain): - (JSC::SlotVisitor::addOpaqueRoot): - (JSC::SlotVisitor::mergeIfNecessary): - (JSC::SlotVisitor::mergeOpaqueRootsIfNecessary): Deleted. - * heap/SlotVisitor.h: - (JSC::SlotVisitor::setIgnoreNewOpaqueRoots): - * heap/SlotVisitorInlines.h: - (JSC::SlotVisitor::reportExtraMemoryVisited): - (JSC::SlotVisitor::reportExternalMemoryVisited): - * heap/Subspace.cpp: Added. - (JSC::Subspace::Subspace): - (JSC::Subspace::~Subspace): - (JSC::Subspace::finishSweep): - (JSC::Subspace::destroy): - (JSC::Subspace::allocate): - (JSC::Subspace::tryAllocate): - (JSC::Subspace::allocatorForSlow): - (JSC::Subspace::allocateSlow): - (JSC::Subspace::tryAllocateSlow): - * heap/Subspace.h: Added. - (JSC::Subspace::tryAllocatorFor): - (JSC::Subspace::allocatorFor): - * heap/SubspaceInlines.h: Added. - (JSC::Subspace::forEachMarkedBlock): - (JSC::Subspace::forEachNotEmptyMarkedBlock): - (JSC::Subspace::forEachLargeAllocation): - (JSC::Subspace::forEachMarkedCell): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::specializedVisit): - * heap/WeakBlock.h: - * heap/WeakSet.h: - (JSC::WeakSet::visit): - * jit/AssemblyHelpers.h: - (JSC::AssemblyHelpers::emitAllocateJSObjectWithKnownSize): - (JSC::AssemblyHelpers::emitAllocateVariableSized): - (JSC::AssemblyHelpers::emitAllocateVariableSizedCell): - * jit/JITOpcodes.cpp: - (JSC::JIT::emit_op_new_object): - * jsc.cpp: - * runtime/ButterflyInlines.h: - (JSC::Butterfly::createUninitialized): - (JSC::Butterfly::growArrayRight): - * runtime/ClassInfo.h: - * runtime/ClonedArguments.cpp: - (JSC::ClonedArguments::createEmpty): - * runtime/DirectArguments.cpp: - (JSC::DirectArguments::overrideThings): - * runtime/GenericArgumentsInlines.h: - (JSC::GenericArguments::initModifiedArgumentsDescriptor): - * runtime/HashMapImpl.h: - (JSC::HashMapBuffer::create): - * runtime/JSArray.cpp: - (JSC::JSArray::tryCreateUninitialized): - (JSC::JSArray::unshiftCountSlowCase): - * runtime/JSArrayBufferView.cpp: - (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext): - * runtime/JSCell.h: - (JSC::subspaceFor): - * runtime/JSCellInlines.h: - (JSC::JSCell::visitOutputConstraints): - (JSC::JSCell::subspaceFor): - (JSC::allocateCell): - * runtime/JSDestructibleObject.h: - (JSC::JSDestructibleObject::subspaceFor): - * runtime/JSDestructibleObjectSubspace.cpp: Added. - (JSC::JSDestructibleObjectSubspace::JSDestructibleObjectSubspace): - (JSC::JSDestructibleObjectSubspace::~JSDestructibleObjectSubspace): - (JSC::JSDestructibleObjectSubspace::finishSweep): - (JSC::JSDestructibleObjectSubspace::destroy): - * runtime/JSDestructibleObjectSubspace.h: Added. - * runtime/JSObject.h: - (JSC::JSObject::JSObject): - * runtime/JSObjectInlines.h: - * runtime/JSSegmentedVariableObject.h: - * runtime/JSString.h: - (JSC::JSString::subspaceFor): - * runtime/JSStringSubspace.cpp: Added. - (JSC::JSStringSubspace::JSStringSubspace): - (JSC::JSStringSubspace::~JSStringSubspace): - (JSC::JSStringSubspace::finishSweep): - (JSC::JSStringSubspace::destroy): - * runtime/JSStringSubspace.h: Added. - * runtime/RegExpMatchesArray.h: - (JSC::tryCreateUninitializedRegExpMatchesArray): - * runtime/VM.cpp: - (JSC::VM::VM): - * runtime/VM.h: - -2017-01-18 Matthew Hanson - - Merge r210829. rdar://problem/30044439 - - 2017-01-16 Filip Pizlo - - JSCell::classInfo() shouldn't have a bunch of mitigations for being called during destruction - https://bugs.webkit.org/show_bug.cgi?id=167066 - - Reviewed by Keith Miller and Michael Saboff. - - This reduces the size of JSCell::classInfo() by half and removes some checks that - this function previously had to do in case it was called from destructors. - - I changed all of the destructors so that they don't call JSCell::classInfo() and I - added an assertion to JSCell::classInfo() to catch cases where someone called it - from a destructor accidentally. - - This means that we only have one place in destruction that needs to know the class: - the sweeper's call to the destructor. - - One of the trickiest outcomes of this is the need to support inherits() tests in - JSObjectGetPrivate(), when it is called from the destructor callback on the object - being destructed. JSObjectGetPrivate() is undefined behavior anyway if you use it - on any dead-but-not-destructed object other than the one being destructed right - now. The purpose of the inherits() tests is to distinguish between different kinds - of CallbackObjects, which may have different kinds of base classes. I think that - this was always subtly wrong - for example, if the object being destructed is a - JSGlobalObject then it's not a DestructibleObject, is not in a destructor block, - but does not have an immortal Structure - so classInfo() is not valid. This fixes - the issue by having ~JSCallbackObject know its classInfo. It now stashes its - classInfo in VM so that JSObjectGetPrivate can use that classInfo if it detects - that it's being used on a currently-destructing object. - - That was the only really weird part of this patch. The rest is mostly removing - illegal uses of jsCast<> in destructors. There were a few other genuine uses of - classInfo() but they were in code that already knew how to get its classInfo() - using other means: - - - You can still say structure()->classInfo(), and I use this form in code that - knows that its StructureIsImmortal. - - - You can use this->classInfo() if it's overridden, like in subclasses of - JSDestructibleObject. - - Rolling this back in because I think I fixed the crashes. - - * API/JSAPIWrapperObject.mm: - (JSAPIWrapperObjectHandleOwner::finalize): - * API/JSCallbackObject.h: - * API/JSCallbackObjectFunctions.h: - (JSC::JSCallbackObject::~JSCallbackObject): - (JSC::JSCallbackObject::init): - * API/JSObjectRef.cpp: - (classInfoPrivate): - (JSObjectGetPrivate): - (JSObjectSetPrivate): - * bytecode/EvalCodeBlock.cpp: - (JSC::EvalCodeBlock::destroy): - * bytecode/FunctionCodeBlock.cpp: - (JSC::FunctionCodeBlock::destroy): - * bytecode/ModuleProgramCodeBlock.cpp: - (JSC::ModuleProgramCodeBlock::destroy): - * bytecode/ProgramCodeBlock.cpp: - (JSC::ProgramCodeBlock::destroy): - * bytecode/UnlinkedEvalCodeBlock.cpp: - (JSC::UnlinkedEvalCodeBlock::destroy): - * bytecode/UnlinkedFunctionCodeBlock.cpp: - (JSC::UnlinkedFunctionCodeBlock::destroy): - * bytecode/UnlinkedFunctionExecutable.cpp: - (JSC::UnlinkedFunctionExecutable::destroy): - * bytecode/UnlinkedModuleProgramCodeBlock.cpp: - (JSC::UnlinkedModuleProgramCodeBlock::destroy): - * bytecode/UnlinkedProgramCodeBlock.cpp: - (JSC::UnlinkedProgramCodeBlock::destroy): - * heap/CodeBlockSet.cpp: - (JSC::CodeBlockSet::lastChanceToFinalize): - (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::allocateSlowCaseImpl): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::Handle::sweep): - * jit/JITThunks.cpp: - (JSC::JITThunks::finalize): - * runtime/AbstractModuleRecord.cpp: - (JSC::AbstractModuleRecord::destroy): - * runtime/ExecutableBase.cpp: - (JSC::ExecutableBase::clearCode): - * runtime/JSCellInlines.h: - (JSC::JSCell::classInfo): - (JSC::JSCell::callDestructor): - * runtime/JSLock.h: - (JSC::JSLock::ownerThread): - * runtime/JSModuleNamespaceObject.cpp: - (JSC::JSModuleNamespaceObject::destroy): - * runtime/JSModuleRecord.cpp: - (JSC::JSModuleRecord::destroy): - * runtime/JSPropertyNameEnumerator.cpp: - (JSC::JSPropertyNameEnumerator::destroy): - * runtime/JSSegmentedVariableObject.h: - * runtime/SymbolTable.cpp: - (JSC::SymbolTable::destroy): - * runtime/VM.h: - * wasm/js/JSWebAssemblyCallee.cpp: - (JSC::JSWebAssemblyCallee::destroy): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::destroy): - * wasm/js/WebAssemblyToJSCallee.cpp: - (JSC::WebAssemblyToJSCallee::WebAssemblyToJSCallee): - (JSC::WebAssemblyToJSCallee::destroy): - -2017-01-18 Matthew Hanson - - Merge r210745. rdar://problem/30019309 - - 2017-01-13 Saam Barati - - Initialize the ArraySpecies watchpoint as Clear and transition to IsWatched once slice is called for the first time - https://bugs.webkit.org/show_bug.cgi?id=167017 - - - Reviewed by Keith Miller and Filip Pizlo. - - This patch is to reverse the JSBench regression from r210695. - - The new state diagram for the array species watchpoint is as - follows: - - 1. On GlobalObject construction, it starts life out as ClearWatchpoint. - 2. When slice is called for the first time, we observe the state - of the world, and either transition it to IsWatched if we were able - to set up the object property conditions, or to IsInvalidated if we - were not. - 3. The DFG compiler will now only lower slice as an intrinsic if - it observed the speciesWatchpoint.state() as IsWatched. - 4. The IsWatched => IsInvalidated transition happens only when - one of the object property condition watchpoints fire. - - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleIntrinsicCall): - * runtime/ArrayPrototype.cpp: - (JSC::speciesWatchpointIsValid): - (JSC::speciesConstructArray): - (JSC::arrayProtoPrivateFuncConcatMemcpy): - (JSC::ArrayPrototype::tryInitializeSpeciesWatchpoint): - (JSC::ArrayPrototype::initializeSpeciesWatchpoint): Deleted. - * runtime/ArrayPrototype.h: - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC::JSGlobalObject::init): - -2017-01-18 Matthew Hanson - - Merge r210695. rdar://problem/29913445 - - 2017-01-12 Saam Barati - - Add a slice intrinsic to the DFG/FTL - https://bugs.webkit.org/show_bug.cgi?id=166707 - - - Reviewed by Filip Pizlo. - - The gist of this patch is to inline Array.prototype.slice - into the DFG/FTL. The implementation in the DFG-backend - and FTLLowerDFGToB3 is just a straight forward implementation - of what the C function is doing. The more interesting bits - of this patch are setting up the proper watchpoints and conditions - in the executing code to prove that its safe to skip all of the - observable JS actions that Array.prototype.slice normally does. - - We perform the following proofs: - 1. Array.prototype.constructor has not changed (via a watchpoint). - 2. That Array.prototype.constructor[Symbol.species] has not changed (via a watchpoint). - 3. The global object is not having a bad time. - 4. The array that is being sliced has an original array structure. - 5. Array.prototype/Object.prototype have not transitioned. - - Conditions 1, 2, and 3 are strictly required. - - 4 is ensuring a couple things: - 1. That a "constructor" property hasn't been added to the array - we're slicing since we're supposed to perform a Get(array, "constructor"). - 2. That we're not slicing an instance of a subclass of Array. - - We could relax 4.1 in the future if we find other ways to test if - the incoming array hasn't changed the "constructor" property. We - would probably use TryGetById to do this. - - I'm seeing a 5% speedup on crypto-pbkdf2 and often a 1% speedup on - the total benchmark (the results are sometimes noisy). - - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::executeEffects): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handleIntrinsicCall): - * dfg/DFGCallArrayAllocatorSlowPathGenerator.h: - (JSC::DFG::CallArrayAllocatorWithVariableStructureVariableSizeSlowPathGenerator::CallArrayAllocatorWithVariableStructureVariableSizeSlowPathGenerator): - * dfg/DFGClobberize.h: - (JSC::DFG::clobberize): - * dfg/DFGDoesGC.cpp: - (JSC::DFG::doesGC): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGNodeType.h: - * dfg/DFGPredictionPropagationPhase.cpp: - * dfg/DFGSafeToExecute.h: - (JSC::DFG::safeToExecute): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileArraySlice): - (JSC::DFG::SpeculativeJIT::emitAllocateButterfly): - * dfg/DFGSpeculativeJIT.h: - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::emitInitializeButterfly): - (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - (JSC::DFG::SpeculativeJIT::emitInitializeButterfly): - (JSC::DFG::SpeculativeJIT::compileAllocateNewArrayWithSize): - * ftl/FTLAbstractHeapRepository.h: - * ftl/FTLCapabilities.cpp: - (JSC::FTL::canCompile): - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::compileNode): - (JSC::FTL::DFG::LowerDFGToB3::compileArraySlice): - (JSC::FTL::DFG::LowerDFGToB3::compileNewArrayWithSize): - (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): - (JSC::FTL::DFG::LowerDFGToB3::initializeArrayElements): - (JSC::FTL::DFG::LowerDFGToB3::storeStructure): - (JSC::FTL::DFG::LowerDFGToB3::allocateCell): - (JSC::FTL::DFG::LowerDFGToB3::allocateObject): - (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray): - (JSC::FTL::DFG::LowerDFGToB3::allocateUninitializedContiguousJSArray): - * jit/AssemblyHelpers.cpp: - (JSC::AssemblyHelpers::emitLoadStructure): - * runtime/ArrayPrototype.cpp: - (JSC::ArrayPrototype::finishCreation): - (JSC::speciesWatchpointIsValid): - (JSC::speciesConstructArray): - (JSC::arrayProtoFuncSlice): - (JSC::arrayProtoPrivateFuncConcatMemcpy): - (JSC::ArrayPrototype::initializeSpeciesWatchpoint): - (JSC::ArrayPrototypeAdaptiveInferredPropertyWatchpoint::handleFire): - (JSC::speciesWatchpointsValid): Deleted. - (JSC::ArrayPrototype::attemptToInitializeSpeciesWatchpoint): Deleted. - * runtime/ArrayPrototype.h: - (JSC::ArrayPrototype::speciesWatchpointStatus): Deleted. - (): Deleted. - * runtime/Intrinsic.h: - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::JSGlobalObject): - (JSC::JSGlobalObject::init): - * runtime/JSGlobalObject.h: - (JSC::JSGlobalObject::arraySpeciesWatchpoint): - * runtime/Structure.h: - -2017-01-18 Matthew Hanson - - Merge r210837. rdar://problem/29432371 - - 2017-01-17 Michael Saboff - - Nested parenthesized regular expressions with non-zero minimum counts appear to hang and use lots of memory - https://bugs.webkit.org/show_bug.cgi?id=167125 - - Reviewed by Filip Pizlo. - - Changed Yarr to handle nested parenthesized subexpressions where the minimum count is - not 0 directly in the Yarr interpreter. Previously we'd factor an expression like - (a|b)+ into (a|b)(a|b)* with special handling for captures. This factoring was done - using a deep copy that doubled the size of the resulting expresion for each nested - parenthesized subexpression. Now the Yarr interpreter can directly process a regexp - like (a|b){2,42}. - - The parser will allow one level of nested, non-zero minimum, counted parenthesis using - the old copy method. After one level, it will generate parenthesis terms with a non-zero - minimum. Such an expression wasn't handled by the Yarr JIT before the change, so this - change isn't a performance regression. - - Added a minimum count to the YarrPattern and ByteTerm classes, and then factored that - minimum into the interpreter. A non-zero minimum is only handled by the Yarr interpreter. - If the Yarr JIT see such a term, it punts back to the interpreter. - - * yarr/YarrInterpreter.cpp: - (JSC::Yarr::Interpreter::backtrackPatternCharacter): - (JSC::Yarr::Interpreter::backtrackPatternCasedCharacter): - (JSC::Yarr::Interpreter::matchCharacterClass): - (JSC::Yarr::Interpreter::backtrackCharacterClass): - (JSC::Yarr::Interpreter::matchBackReference): - (JSC::Yarr::Interpreter::backtrackBackReference): - (JSC::Yarr::Interpreter::matchParenthesesOnceBegin): - (JSC::Yarr::Interpreter::matchParenthesesOnceEnd): - (JSC::Yarr::Interpreter::backtrackParenthesesOnceBegin): - (JSC::Yarr::Interpreter::backtrackParenthesesOnceEnd): - (JSC::Yarr::Interpreter::matchParenthesesTerminalBegin): - (JSC::Yarr::Interpreter::backtrackParenthesesTerminalBegin): - (JSC::Yarr::Interpreter::matchParentheticalAssertionBegin): - (JSC::Yarr::Interpreter::matchParentheticalAssertionEnd): - (JSC::Yarr::Interpreter::backtrackParentheticalAssertionBegin): - (JSC::Yarr::Interpreter::backtrackParentheticalAssertionEnd): - (JSC::Yarr::Interpreter::matchParentheses): - (JSC::Yarr::Interpreter::backtrackParentheses): - (JSC::Yarr::Interpreter::matchDisjunction): - (JSC::Yarr::ByteCompiler::atomPatternCharacter): - (JSC::Yarr::ByteCompiler::atomCharacterClass): - (JSC::Yarr::ByteCompiler::atomBackReference): - (JSC::Yarr::ByteCompiler::atomParentheticalAssertionEnd): - (JSC::Yarr::ByteCompiler::atomParenthesesSubpatternEnd): - (JSC::Yarr::ByteCompiler::atomParenthesesOnceEnd): - (JSC::Yarr::ByteCompiler::atomParenthesesTerminalEnd): - (JSC::Yarr::ByteCompiler::emitDisjunction): - * yarr/YarrInterpreter.h: - (JSC::Yarr::ByteTerm::ByteTerm): - * yarr/YarrJIT.cpp: - (JSC::Yarr::YarrGenerator::generatePatternCharacterOnce): - (JSC::Yarr::YarrGenerator::generatePatternCharacterFixed): - (JSC::Yarr::YarrGenerator::generatePatternCharacterGreedy): - (JSC::Yarr::YarrGenerator::backtrackPatternCharacterNonGreedy): - (JSC::Yarr::YarrGenerator::generateCharacterClassFixed): - (JSC::Yarr::YarrGenerator::generateCharacterClassGreedy): - (JSC::Yarr::YarrGenerator::backtrackCharacterClassNonGreedy): - (JSC::Yarr::YarrGenerator::generateTerm): - (JSC::Yarr::YarrGenerator::backtrackTerm): - (JSC::Yarr::YarrGenerator::generate): - (JSC::Yarr::YarrGenerator::backtrack): - (JSC::Yarr::YarrGenerator::opCompileParenthesesSubpattern): - * yarr/YarrPattern.cpp: - (JSC::Yarr::YarrPatternConstructor::copyTerm): - (JSC::Yarr::YarrPatternConstructor::quantifyAtom): - (JSC::Yarr::YarrPatternConstructor::checkForTerminalParentheses): - (JSC::Yarr::YarrPattern::YarrPattern): - * yarr/YarrPattern.h: - (JSC::Yarr::PatternTerm::PatternTerm): - (JSC::Yarr::PatternTerm::quantify): - (JSC::Yarr::YarrPattern::reset): - -2017-01-13 Matthew Hanson - - Merge r210694. rdar://problem/29983526 - - 2017-01-12 Saam Barati - - Concurrent GC has a bug where we would detect a race but fail to rescan the object - https://bugs.webkit.org/show_bug.cgi?id=166960 - - - Reviewed by Filip Pizlo and Mark Lam. - - We have code like this in JSC: - - ``` - Butterfly* butterfly = allocateMoreOutOfLineStorage(vm, oldOutOfLineCapacity, newOutOfLineCapacity); - nukeStructureAndSetButterfly(vm, structureID, butterfly); - structure->setLastOffset(newLastOffset); - WTF::storeStoreFence(); - setStructureIDDirectly(structureID); - ``` - - Note that the collector could detect a race here, which sometimes - incorrectly caused us to not visit the object again. - - Mutator Thread: M, Collector Thread: C, assuming sequential consistency via - proper barriers: - - M: allocate new butterfly - M: Set nuked structure ID - M: Set butterfly (this does a barrier) - C: Start scanning O - C: load structure ID - C: See it's nuked and bail, (we used to rely on a write barrier to rescan). - - We sometimes never rescanned here because we were calling - setStructureIDDirectly which doesn't do a write barrier. - (Note, the places that do this but call setStructure were - OK because setStructure will perform a write barrier.) - - (This same issue also existed in places where the collector thread - detected races for Structure::m_offset, but places that changed - Structure::m_offset didn't perform a write barrier on the object - after changing its Structure's m_offset.) - - To prevent such code from requiring every call site to perform - a write barrier on the object, I've changed the collector code - to keep a stack of cells to be revisited due to races. This stack - is then consulted when we do marking. Because such races are rare, - we have a single stack on Heap that is guarded by a lock. - - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::~Heap): - (JSC::Heap::markToFixpoint): - (JSC::Heap::endMarking): - (JSC::Heap::buildConstraintSet): - (JSC::Heap::addToRaceMarkStack): - * heap/Heap.h: - (JSC::Heap::collectorSlotVisitor): - (JSC::Heap::mutatorMarkStack): Deleted. - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::didRace): - * heap/SlotVisitor.h: - (JSC::SlotVisitor::didRace): - (JSC::SlotVisitor::didNotRace): Deleted. - * heap/SlotVisitorInlines.h: - (JSC::SlotVisitor::didNotRace): Deleted. - * runtime/JSObject.cpp: - (JSC::JSObject::visitButterfly): - (JSC::JSObject::visitButterflyImpl): - * runtime/JSObjectInlines.h: - (JSC::JSObject::prepareToPutDirectWithoutTransition): - * runtime/Structure.cpp: - (JSC::Structure::flattenDictionaryStructure): - -2017-01-12 Matthew Hanson - - Merge r210609. rdar://problem/27896585 - - 2017-01-11 Andreas Kling - - Crash when WebCore's GC heap grows way too large. - - - - Reviewed by Mark Lam. - - Add a simple API to JSC::Heap that allows setting a hard limit on the amount - of live bytes. If this is exceeded, we crash with a recognizable signature. - By default there is no limit. - - * heap/Heap.cpp: - (JSC::Heap::didExceedMaxLiveSize): - (JSC::Heap::updateAllocationLimits): - * heap/Heap.h: - (JSC::Heap::setMaxLiveSize): - -2017-01-12 Matthew Hanson - - Merge r210565. rdar://problem/29942167 - - 2017-01-09 Filip Pizlo - - Streamline the GC barrier slowpath - https://bugs.webkit.org/show_bug.cgi?id=166878 - - Reviewed by Geoffrey Garen and Saam Barati. - - This implements two optimizations to the barrier: - - - Removes the write barrier buffer. This was just overhead. - - - Teaches the slow path how to white an object that was black but unmarked, ensuring that - we don't take slow path for this object again. - - * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileStoreBarrier): - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::emitStoreBarrier): - * heap/CellState.h: - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::markToFixpoint): - (JSC::Heap::addToRememberedSet): - (JSC::Heap::stopTheWorld): - (JSC::Heap::writeBarrierSlowPath): - (JSC::Heap::buildConstraintSet): - (JSC::Heap::flushWriteBarrierBuffer): Deleted. - * heap/Heap.h: - (JSC::Heap::writeBarrierBuffer): Deleted. - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::appendJSCellOrAuxiliary): - (JSC::SlotVisitor::setMarkedAndAppendToMarkStack): - (JSC::SlotVisitor::appendToMarkStack): - (JSC::SlotVisitor::visitChildren): - * heap/WriteBarrierBuffer.cpp: Removed. - * heap/WriteBarrierBuffer.h: Removed. - * jit/JITOperations.cpp: - * jit/JITOperations.h: - * runtime/JSCellInlines.h: - (JSC::JSCell::JSCell): - * runtime/StructureIDBlob.h: - (JSC::StructureIDBlob::StructureIDBlob): - -2017-01-12 Matthew Hanson - - Merge r210563. rdar://problem/29940224 - - 2017-01-10 Mark Lam - - Property setters should not be called for bound arguments list entries. - https://bugs.webkit.org/show_bug.cgi?id=165631 - - Reviewed by Filip Pizlo. - - * builtins/FunctionPrototype.js: - (bind): - - use @putByValDirect to set the bound arguments so that we don't consult the - prototype chain for setters. - - * runtime/IntlDateTimeFormatPrototype.cpp: - (JSC::IntlDateTimeFormatPrototypeGetterFormat): - * runtime/IntlNumberFormatPrototype.cpp: - (JSC::IntlNumberFormatPrototypeGetterFormat): - - no need to create a bound arguments array because these bound functions binds - no arguments according to the spec. - -2017-01-12 Matthew Hanson - - Merge r210553. rdar://problem/29941356 - - 2017-01-09 Filip Pizlo - - JSArray has some object scanning races - https://bugs.webkit.org/show_bug.cgi?id=166874 - - Reviewed by Mark Lam. - - This fixes two separate bugs, both of which I detected by running - array-splice-contiguous.js in extreme anger: - - 1) Some of the paths of shifting and unshifting were not grabbing the internal cell - lock. This was causing the array storage scan to crash, even though it was well - synchronized (the scan does hold the lock). The fix is just to hold the lock anywhere - that memmoves the innards of the butterfly. - - 2) Out of line property scanning was synchronized using double collect snapshot. Array - storage scanning was synchronized using locks. But what if array storage - transformations messed up the out of line properties? It turns out that we actually - need to hoist the array storage scanner's locking up into the double collect - snapshot. - - I don't know how to write a test that does any better of a job of catching this than - array-splice-contiguous.js. - - * heap/DeferGC.h: Make DisallowGC usable even if NDEBUG. - * runtime/JSArray.cpp: - (JSC::JSArray::unshiftCountSlowCase): - (JSC::JSArray::shiftCountWithArrayStorage): - (JSC::JSArray::unshiftCountWithArrayStorage): - * runtime/JSObject.cpp: - (JSC::JSObject::visitButterflyImpl): - -2017-01-12 Matthew Hanson - - Merge r210530. rdar://problem/29909896 - - 2017-01-09 Filip Pizlo - - Unreviewed, fix cloop. - - * dfg/DFGPlanInlines.h: - -2017-01-12 Matthew Hanson - - Merge r210521. rdar://problem/29909896 - - 2017-01-08 Filip Pizlo - - Make the collector's fixpoint smart about scheduling work - https://bugs.webkit.org/show_bug.cgi?id=165910 - - Reviewed by Keith Miller. - - Prior to this change, every time the GC would run any constraints in markToFixpoint, it - would run all of the constraints. It would always run them in the same order. That means - that so long as any one constraint was generating new work, we'd pay the price of all - constraints. This is usually OK because most constraints are cheap but it artificially - inflates the cost of slow constraints - especially ones that are expensive but usually - generate no new work. - - This patch redoes how the GC runs constraints by applying ideas from data flow analysis. - The GC now builds a MarkingConstraintSet when it boots up, and this contains all of the - constraints as well as some meta-data about them. Now, markToFixpoint just calls into - MarkingConstraintSet to execute constraints. Because constraint execution and scheduling - need to be aware of each other, I rewrote markToFixpoint in such a way that it's more - obvious how the GC goes between constraint solving, marking with stopped mutator, and - marking with resumed mutator. This also changes the scheduler API in such a way that a - synchronous stop-the-world collection no longer needs to do fake stop/resume - instead we - just swap the space-time scheduler for the stop-the-world scheduler. - - This is a big streamlining of the GC. This is a speed-up in GC-heavy tests because we - now execute most constraints exactly twice regardless of how many total fixpoint - iterations we do. Now, when we run out of marking work, the constraint solver will just - run the constraint that is most likely to generate new visiting work, and if it does - generate work, then the GC now goes back to marking. Before, it would run *all* - constraints and then go back to marking. The constraint solver is armed with three - information signals that it uses to sort the constraints in order of descending likelihood - to generate new marking work. Then it runs them in that order until it there is new - marking work. The signals are: - - 1) Whether the constraint is greyed by marking or execution. We call this the volatility - of the constraint. For example, weak reference constraints have GreyedByMarking as - their volatility because they are most likely to have something to say after we've done - some marking. On the other hand, conservative roots have GreyedByExecution as their - volatility because they will give new information anytime we let the mutator run. The - constraint solver will only run GreyedByExecution constraints as roots and after the - GreyedByMarking constraints go silent. This ensures that we don't try to scan - conservative roots every time we need to re-run weak references and vice-versa. - - Another way to look at it is that the constraint solver tries to predict if the - wavefront is advancing or retreating. The wavefront is almost certainly advancing so - long as the mark stacks are non-empty or so long as at least one of the GreyedByMarking - constraints is still producing work. Otherwise the wavefront is almost certainly - retreating. It's most profitable to run GreyedByMarking constraints when the wavefront - is advancing, and most profitable to run GreyedByExecution constraints when the - wavefront is retreating. - - We use the predicted wavefront direction and the volatility of constraints as a - first-order signal of constraint profitability. - - 2) How much visiting work was created the last time the constraint ran. The solver - remembers the lastVisitCount, and uses it to predict how much work the constraint will - generate next time. In practice this means we will keep re-running the one interesting - constraint until it shuts up. - - 3) Optional work predictors for some constraints. The constraint that shuffles the mutator - mark stack into the main SlotVisitor's mutator mark stack always knows exactly how much - work it will create. - - The sum of (2) and (3) are used as a second-order signal of constraint profitability. - - The constraint solver will always run all of the GreyedByExecution constraints at GC - start, since these double as the GC's roots. The constraint solver will always run all of - the GreyedByMarking constraints the first time that marking stalls. Other than that, the - solver will keep running constraints, sorted according to their likelihood to create work, - until either work is created or we run out of constraints to run. GC termination happens - when we run out of constraints to run. - - This new infrastructure means that we have a much better chance of dealing with worst-case - DOM pathologies. If we can intelligently factor different evil DOM things into different - constraints with the right work predictions then this could reduce the cost of those DOM - things by a factor of N where N is the number of fixpoint iterations the GC typically - does. N is usually around 5-6 even for simple heaps. - - My perf measurements say: - - PLT3: 0.02% faster with 5.3% confidence. - JetStream: 0.15% faster with 17% confidence. - Speedometer: 0.58% faster with 82% confidence. - - Here are the details from JetStream: - - splay: 1.02173x faster with 0.996841 confidence - splay-latency: 1.0617x faster with 0.987462 confidence - towers.c: 1.01852x faster with 0.92128 confidence - crypto-md5: 1.06058x faster with 0.482363 confidence - score: 1.00152x faster with 0.16892 confidence - - I think that Speedometer is legitimately benefiting from this change based on looking at - --logGC=true output. We are now spending less time reexecuting expensive constraints. I - think that JetStream/splay is also benefiting, because although the constraints it sees - are cheap, it spends 30% of its time in GC so even small improvements matter. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * dfg/DFGPlan.cpp: - (JSC::DFG::Plan::markCodeBlocks): Deleted. - (JSC::DFG::Plan::rememberCodeBlocks): Deleted. - * dfg/DFGPlan.h: - * dfg/DFGPlanInlines.h: Added. - (JSC::DFG::Plan::iterateCodeBlocksForGC): - * dfg/DFGWorklist.cpp: - (JSC::DFG::Worklist::markCodeBlocks): Deleted. - (JSC::DFG::Worklist::rememberCodeBlocks): Deleted. - (JSC::DFG::rememberCodeBlocks): Deleted. - * dfg/DFGWorklist.h: - * dfg/DFGWorklistInlines.h: Added. - (JSC::DFG::iterateCodeBlocksForGC): - (JSC::DFG::Worklist::iterateCodeBlocksForGC): - * heap/CodeBlockSet.cpp: - (JSC::CodeBlockSet::writeBarrierCurrentlyExecuting): Deleted. - * heap/CodeBlockSet.h: - (JSC::CodeBlockSet::iterate): Deleted. - * heap/CodeBlockSetInlines.h: - (JSC::CodeBlockSet::iterate): - (JSC::CodeBlockSet::iterateCurrentlyExecuting): - * heap/Heap.cpp: - (JSC::Heap::Heap): - (JSC::Heap::iterateExecutingAndCompilingCodeBlocks): - (JSC::Heap::iterateExecutingAndCompilingCodeBlocksWithoutHoldingLocks): - (JSC::Heap::assertSharedMarkStacksEmpty): - (JSC::Heap::markToFixpoint): - (JSC::Heap::endMarking): - (JSC::Heap::collectInThread): - (JSC::Heap::stopIfNecessarySlow): - (JSC::Heap::acquireAccessSlow): - (JSC::Heap::collectIfNecessaryOrDefer): - (JSC::Heap::buildConstraintSet): - (JSC::Heap::notifyIsSafeToCollect): - (JSC::Heap::ResumeTheWorldScope::ResumeTheWorldScope): Deleted. - (JSC::Heap::ResumeTheWorldScope::~ResumeTheWorldScope): Deleted. - (JSC::Heap::harvestWeakReferences): Deleted. - (JSC::Heap::visitConservativeRoots): Deleted. - (JSC::Heap::visitCompilerWorklistWeakReferences): Deleted. - * heap/Heap.h: - * heap/MarkingConstraint.cpp: Added. - (JSC::MarkingConstraint::MarkingConstraint): - (JSC::MarkingConstraint::~MarkingConstraint): - (JSC::MarkingConstraint::resetStats): - (JSC::MarkingConstraint::execute): - * heap/MarkingConstraint.h: Added. - (JSC::MarkingConstraint::index): - (JSC::MarkingConstraint::abbreviatedName): - (JSC::MarkingConstraint::name): - (JSC::MarkingConstraint::lastVisitCount): - (JSC::MarkingConstraint::quickWorkEstimate): - (JSC::MarkingConstraint::workEstimate): - (JSC::MarkingConstraint::volatility): - * heap/MarkingConstraintSet.cpp: Added. - (JSC::MarkingConstraintSet::ExecutionContext::ExecutionContext): - (JSC::MarkingConstraintSet::ExecutionContext::didVisitSomething): - (JSC::MarkingConstraintSet::ExecutionContext::shouldTimeOut): - (JSC::MarkingConstraintSet::ExecutionContext::drain): - (JSC::MarkingConstraintSet::ExecutionContext::didExecute): - (JSC::MarkingConstraintSet::ExecutionContext::execute): - (JSC::MarkingConstraintSet::MarkingConstraintSet): - (JSC::MarkingConstraintSet::~MarkingConstraintSet): - (JSC::MarkingConstraintSet::resetStats): - (JSC::MarkingConstraintSet::add): - (JSC::MarkingConstraintSet::executeBootstrap): - (JSC::MarkingConstraintSet::executeConvergence): - (JSC::MarkingConstraintSet::isWavefrontAdvancing): - (JSC::MarkingConstraintSet::executeConvergenceImpl): - (JSC::MarkingConstraintSet::executeAll): - * heap/MarkingConstraintSet.h: Added. - (JSC::MarkingConstraintSet::isWavefrontRetreating): - * heap/MutatorScheduler.cpp: Added. - (JSC::MutatorScheduler::MutatorScheduler): - (JSC::MutatorScheduler::~MutatorScheduler): - (JSC::MutatorScheduler::didStop): - (JSC::MutatorScheduler::willResume): - (JSC::MutatorScheduler::didExecuteConstraints): - (JSC::MutatorScheduler::log): - (JSC::MutatorScheduler::shouldStop): - (JSC::MutatorScheduler::shouldResume): - * heap/MutatorScheduler.h: Added. - * heap/OpaqueRootSet.h: - (JSC::OpaqueRootSet::add): - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::visitAsConstraint): - (JSC::SlotVisitor::drain): - (JSC::SlotVisitor::didReachTermination): - (JSC::SlotVisitor::hasWork): - (JSC::SlotVisitor::drainFromShared): - (JSC::SlotVisitor::drainInParallelPassively): - (JSC::SlotVisitor::addOpaqueRoot): - * heap/SlotVisitor.h: - (JSC::SlotVisitor::addToVisitCount): - * heap/SpaceTimeMutatorScheduler.cpp: Copied from Source/JavaScriptCore/heap/SpaceTimeScheduler.cpp. - (JSC::SpaceTimeMutatorScheduler::Snapshot::Snapshot): - (JSC::SpaceTimeMutatorScheduler::Snapshot::now): - (JSC::SpaceTimeMutatorScheduler::Snapshot::bytesAllocatedThisCycle): - (JSC::SpaceTimeMutatorScheduler::SpaceTimeMutatorScheduler): - (JSC::SpaceTimeMutatorScheduler::~SpaceTimeMutatorScheduler): - (JSC::SpaceTimeMutatorScheduler::state): - (JSC::SpaceTimeMutatorScheduler::beginCollection): - (JSC::SpaceTimeMutatorScheduler::didStop): - (JSC::SpaceTimeMutatorScheduler::willResume): - (JSC::SpaceTimeMutatorScheduler::didExecuteConstraints): - (JSC::SpaceTimeMutatorScheduler::timeToStop): - (JSC::SpaceTimeMutatorScheduler::timeToResume): - (JSC::SpaceTimeMutatorScheduler::log): - (JSC::SpaceTimeMutatorScheduler::endCollection): - (JSC::SpaceTimeMutatorScheduler::bytesAllocatedThisCycleImpl): - (JSC::SpaceTimeMutatorScheduler::bytesSinceBeginningOfCycle): - (JSC::SpaceTimeMutatorScheduler::maxHeadroom): - (JSC::SpaceTimeMutatorScheduler::headroomFullness): - (JSC::SpaceTimeMutatorScheduler::mutatorUtilization): - (JSC::SpaceTimeMutatorScheduler::collectorUtilization): - (JSC::SpaceTimeMutatorScheduler::elapsedInPeriod): - (JSC::SpaceTimeMutatorScheduler::phase): - (JSC::SpaceTimeMutatorScheduler::shouldBeResumed): - (JSC::SpaceTimeScheduler::Decision::targetMutatorUtilization): Deleted. - (JSC::SpaceTimeScheduler::Decision::targetCollectorUtilization): Deleted. - (JSC::SpaceTimeScheduler::Decision::elapsedInPeriod): Deleted. - (JSC::SpaceTimeScheduler::Decision::phase): Deleted. - (JSC::SpaceTimeScheduler::Decision::shouldBeResumed): Deleted. - (JSC::SpaceTimeScheduler::Decision::timeToResume): Deleted. - (JSC::SpaceTimeScheduler::Decision::timeToStop): Deleted. - (JSC::SpaceTimeScheduler::SpaceTimeScheduler): Deleted. - (JSC::SpaceTimeScheduler::snapPhase): Deleted. - (JSC::SpaceTimeScheduler::currentDecision): Deleted. - * heap/SpaceTimeMutatorScheduler.h: Copied from Source/JavaScriptCore/heap/SpaceTimeScheduler.h. - (JSC::SpaceTimeScheduler::Decision::operator bool): Deleted. - * heap/SpaceTimeScheduler.cpp: Removed. - * heap/SpaceTimeScheduler.h: Removed. - * heap/SynchronousStopTheWorldMutatorScheduler.cpp: Added. - (JSC::SynchronousStopTheWorldMutatorScheduler::SynchronousStopTheWorldMutatorScheduler): - (JSC::SynchronousStopTheWorldMutatorScheduler::~SynchronousStopTheWorldMutatorScheduler): - (JSC::SynchronousStopTheWorldMutatorScheduler::state): - (JSC::SynchronousStopTheWorldMutatorScheduler::beginCollection): - (JSC::SynchronousStopTheWorldMutatorScheduler::timeToStop): - (JSC::SynchronousStopTheWorldMutatorScheduler::timeToResume): - (JSC::SynchronousStopTheWorldMutatorScheduler::endCollection): - * heap/SynchronousStopTheWorldMutatorScheduler.h: Added. - * heap/VisitingTimeout.h: Added. - (JSC::VisitingTimeout::VisitingTimeout): - (JSC::VisitingTimeout::visitCount): - (JSC::VisitingTimeout::didVisitSomething): - (JSC::VisitingTimeout::shouldTimeOut): - * runtime/Options.h: - -2017-01-12 Matthew Hanson - - Merge r210457. rdar://problem/27330808 - - 2017-01-06 Michael Saboff - - @putByValDirect in Array.of and Array.from overwrites non-writable/configurable properties - https://bugs.webkit.org/show_bug.cgi?id=153486 - - Reviewed by Saam Barati. - - Moved read only check in putDirect() to all paths. - - * runtime/SparseArrayValueMap.cpp: - (JSC::SparseArrayValueMap::putDirect): - -2017-01-11 Matthew Hanson - - Merge r210451. rdar://problem/29909812 - - 2016-12-30 Filip Pizlo - - DeferGC::~DeferGC should be super cheap - https://bugs.webkit.org/show_bug.cgi?id=166626 - - Reviewed by Saam Barati. - - Right now, ~DeferGC requires running the collector's full collectIfNecessaryOrDefer() - hook, which is super big. Normally, that hook would only be called from GC slow paths, - so it ought to be possible to add complex logic to it. It benefits the GC algorithm to - make that code smart, not necessarily fast. - - The right thing for it to do is to have ~DeferGC check a boolean to see if - collectIfNecessaryOrDefer() had previously deferred anything, and only call it if that - is true. That's what this patch does. - - Unfortunately, this means that we lose the collectAccordingToDeferGCProbability mode, - which we used for two tests. Since I could only see two tests that used this mode, I - felt that it was better to enhance the GC than to keep the tests. I filed bug 166627 to - bring back something like that mode. - - Although this patch does make some paths faster, its real goal is to ensure that bug - 165963 can add more logic to collectIfNecessaryOrDefer() without introducing a big - regression. Until then, I wouldn't be surprised if this patch was a progression, but I'm - not betting on it. - - * heap/Heap.cpp: - (JSC::Heap::collectIfNecessaryOrDefer): - (JSC::Heap::decrementDeferralDepthAndGCIfNeededSlow): - (JSC::Heap::canCollect): Deleted. - (JSC::Heap::shouldCollectHeuristic): Deleted. - (JSC::Heap::shouldCollect): Deleted. - (JSC::Heap::collectAccordingToDeferGCProbability): Deleted. - (JSC::Heap::decrementDeferralDepthAndGCIfNeeded): Deleted. - * heap/Heap.h: - * heap/HeapInlines.h: - (JSC::Heap::incrementDeferralDepth): - (JSC::Heap::decrementDeferralDepth): - (JSC::Heap::decrementDeferralDepthAndGCIfNeeded): - (JSC::Heap::mayNeedToStop): - (JSC::Heap::stopIfNecessary): - * runtime/Options.h: - -2017-01-11 Matthew Hanson - - Merge r210398. rdar://problem/29229439 - - 2017-01-05 Filip Pizlo - - AutomaticThread timeout shutdown leaves a small window where notify() would think that the thread is still running - https://bugs.webkit.org/show_bug.cgi?id=166742 - - Reviewed by Geoffrey Garen. - - Update to new AutomaticThread API. - - * dfg/DFGWorklist.cpp: - -2017-01-10 Matthew Hanson - - Rollout r210336. rdar://problem/29912353 - -2017-01-09 Babak Shafiei - - Merge r210458. rdar://problem/29911919 - - 2017-01-06 Mark Lam - - The ObjC API's JSVirtualMachine's map tables need to be guarded by a lock. - https://bugs.webkit.org/show_bug.cgi?id=166778 - - - Reviewed by Filip Pizlo. - - Now that we have a concurrent GC, access to JSVirtualMachine's - m_externalObjectGraph and m_externalRememberedSet need to be guarded by a lock - since both the GC marker thread and the mutator thread may access them at the - same time. - - * API/JSVirtualMachine.mm: - (-[JSVirtualMachine addExternalRememberedObject:]): - (-[JSVirtualMachine addManagedReference:withOwner:]): - (-[JSVirtualMachine removeManagedReference:withOwner:]): - (-[JSVirtualMachine externalDataMutex]): - (scanExternalObjectGraph): - (scanExternalRememberedSet): - - * API/JSVirtualMachineInternal.h: - - Deleted externalObjectGraph method. There's no need to expose this. - -2017-01-06 Matthew Hanson - - Revert the following merges as part of disabling Web Assembly. rdar://problem/29890343 - - rdar://problem/29735737 - rdar://problem/29747874 - rdar://problem/29758107 - rdar://problem/29759741 - rdar://problem/29760322 - rdar://problem/29760326 - rdar://problem/29760386 - rdar://problem/29760621 - rdar://problem/29762017 - rdar://problem/29782821 - rdar://problem/29782833 - rdar://problem/29784532 - rdar://problem/29791695 - rdar://problem/29793220 - rdar://problem/29793949 - rdar://problem/29795709 - rdar://problem/29803676 - rdar://problem/29814999 - rdar://problem/29815000 - rdar://problem/29841541 - rdar://problem/29844107 - rdar://problem/29856455 - -2017-01-06 Matthew Hanson - - Disable WebAssembly. rdar://problem/29890343 - - Landed on behalf of JF Bastien. - - * runtime/Options.h: - -2017-01-06 Matthew Hanson - - Merge r210276. rdar://problem/28867002 - - 2017-01-04 Saam Barati - - We don't properly handle exceptions inside the nativeCallTrampoline macro in the LLInt - https://bugs.webkit.org/show_bug.cgi?id=163720 - - Reviewed by Mark Lam. - - In the LLInt, we were incorrectly doing the exception check after the call. - Before the exception check, we were unwinding to our caller's - frame under the assumption that our caller was always a JS frame. - This is incorrect, however, because our caller might be a C frame. - One way that it can be a C frame is when C calls to JS, and JS tail - calls to native. This patch fixes this bug by doing unwinding from - the native callee's frame instead of its callers. - - * llint/LowLevelInterpreter32_64.asm: - * llint/LowLevelInterpreter64.asm: - -2017-01-06 Matthew Hanson - - Merge r210259. rdar://problem/29856455 - - 2017-01-03 JF Bastien - - REGRESSION (r210244): Release JSC Stress test failure: wasm.yaml/wasm/js-api/wasm-to-wasm.js.default-wasm - https://bugs.webkit.org/show_bug.cgi?id=166669 - - - Reviewed by Saam Barati. - - Bug #165282 added wasm -> wasm calls, but caused crashes in - release builds because the pinned registers are also callee-saved - and were being clobbered. B3 didn't see itself clobbering them - when no memory was used, and therefore omitted a restore. - - This was causing the C++ code in callWebAssemblyFunction to crash - because $r12 was 0, and it expected it to have its value prior to - the call. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::createJSToWasmWrapper): - -2017-01-06 Matthew Hanson - - Merge r210221. rdar://problem/29449474 - - 2017-01-01 Jeff Miller - - Update user-visible copyright strings to include 2017 - https://bugs.webkit.org/show_bug.cgi?id=166278 - - Reviewed by Dan Bernstein. - - * Info.plist: - -2017-01-05 Matthew Hanson - - Merge r210282. rdar://problem/29760326 - - 2017-01-04 JF Bastien - - WebAssembly JS API: add Module.sections - https://bugs.webkit.org/show_bug.cgi?id=165159 - - - Reviewed by Mark Lam. - - As described in: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodulecustomsections - - This was added for Emscripten, and is likely to be used soon. - - * wasm/WasmFormat.h: custom sections are just name + bytes - * wasm/WasmModuleParser.cpp: parse them, instead of skipping over - * wasm/WasmModuleParser.h: - * wasm/js/WebAssemblyModulePrototype.cpp: construct the Array of - ArrayBuffer as described in the spec - (JSC::webAssemblyModuleProtoCustomSections): - -2017-01-05 Matthew Hanson - - Merge r210229. rdar://problem/29760322 - - 2017-01-02 JF Bastien - - WebAssembly: handle and optimize wasm export → wasm import calls - https://bugs.webkit.org/show_bug.cgi?id=165282 - - Reviewed by Saam Barati. - - - Add a new JSType for WebAssemblyFunction, and use it when creating its - structure. This will is used to quickly detect from wasm whether the import - call is to another wasm module, or whether it's to JS. - - Generate two stubs from the import stub generator: one for wasm->JS and one - for wasm -> wasm. This is done at Module time. Which is called will only be - known at Instance time, once we've received the import object. We want to - avoid codegen at Instance time, so having both around is great. - - Restore the WebAssembly global state (VM top Instance, and pinned registers) - after call / call_indirect, and in the JS->wasm entry stub. - - Pinned registers are now a global thing, not per-Memory, because the wasm -> - wasm stubs are generated at Module time where we don't really have enough - information to do the right thing (doing so would generate too much code). - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * runtime/JSType.h: add WebAssemblyFunctionType as a JSType - * wasm/WasmB3IRGenerator.cpp: significantly rework how calls which - could be external work, and how we save / restore global state: - VM's top Instance, and pinned registers - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::getMemoryBaseAndSize): - (JSC::Wasm::restoreWebAssemblyGlobalState): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmB3IRGenerator.h: - * wasm/WasmBinding.cpp: - (JSC::Wasm::materializeImportJSCell): - (JSC::Wasm::wasmToJS): - (JSC::Wasm::wasmToWasm): the main goal of this patch was adding this function - (JSC::Wasm::exitStubGenerator): - * wasm/WasmBinding.h: - * wasm/WasmFormat.h: Get rid of much of the function index space: - we already have all of its information elsewhere, and as-is it - provides no extra efficiency. - (JSC::Wasm::ModuleInformation::functionIndexSpaceSize): - (JSC::Wasm::ModuleInformation::isImportedFunctionFromFunctionIndexSpace): - (JSC::Wasm::ModuleInformation::signatureIndexFromFunctionIndexSpace): - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::FunctionParser): - * wasm/WasmMemory.cpp: Add some logging. - (JSC::Wasm::Memory::dump): this was nice when debugging - (JSC::Wasm::Memory::makeString): - (JSC::Wasm::Memory::Memory): - (JSC::Wasm::Memory::~Memory): - (JSC::Wasm::Memory::grow): - * wasm/WasmMemory.h: don't use extra indirection, it wasn't - needed. Reorder some of the fields which are looked up at runtime - so they're more cache-friendly. - (JSC::Wasm::Memory::Memory): - (JSC::Wasm::Memory::mode): - (JSC::Wasm::Memory::offsetOfSize): - * wasm/WasmMemoryInformation.cpp: Pinned registers are now a - global thing for all of JSC, not a per-Memory thing - anymore. wasm->wasm calls are more complex otherwise: they have to - figure out how to bridge between the caller and callee's - special-snowflake pinning. - (JSC::Wasm::PinnedRegisterInfo::get): - (JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo): - (JSC::Wasm::MemoryInformation::MemoryInformation): - * wasm/WasmMemoryInformation.h: - * wasm/WasmModuleParser.cpp: - * wasm/WasmModuleParser.h: - * wasm/WasmPageCount.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.h. - (JSC::Wasm::PageCount::dump): nice for debugging - * wasm/WasmPageCount.h: - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::parseAndValidateModule): - (JSC::Wasm::Plan::run): - * wasm/WasmPlan.h: - (JSC::Wasm::Plan::takeWasmExitStubs): - * wasm/WasmSignature.cpp: - (JSC::Wasm::Signature::toString): - (JSC::Wasm::Signature::dump): - * wasm/WasmSignature.h: - * wasm/WasmValidate.cpp: - (JSC::Wasm::validateFunction): - * wasm/WasmValidate.h: - * wasm/js/JSWebAssemblyInstance.h: - (JSC::JSWebAssemblyInstance::offsetOfTable): - (JSC::JSWebAssemblyInstance::offsetOfImportFunctions): - (JSC::JSWebAssemblyInstance::offsetOfImportFunction): - * wasm/js/JSWebAssemblyMemory.cpp: - (JSC::JSWebAssemblyMemory::create): - (JSC::JSWebAssemblyMemory::JSWebAssemblyMemory): - (JSC::JSWebAssemblyMemory::buffer): - (JSC::JSWebAssemblyMemory::grow): - * wasm/js/JSWebAssemblyMemory.h: - (JSC::JSWebAssemblyMemory::memory): - (JSC::JSWebAssemblyMemory::offsetOfMemory): - (JSC::JSWebAssemblyMemory::offsetOfSize): - * wasm/js/JSWebAssemblyModule.cpp: - (JSC::JSWebAssemblyModule::create): - (JSC::JSWebAssemblyModule::JSWebAssemblyModule): - * wasm/js/JSWebAssemblyModule.h: - (JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace): - (JSC::JSWebAssemblyModule::functionImportCount): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - (JSC::WebAssemblyFunction::create): - (JSC::WebAssemblyFunction::createStructure): - (JSC::WebAssemblyFunction::WebAssemblyFunction): - (JSC::WebAssemblyFunction::finishCreation): - * wasm/js/WebAssemblyFunction.h: - (JSC::WebAssemblyFunction::wasmEntrypoint): - (JSC::WebAssemblyFunction::offsetOfInstance): - (JSC::WebAssemblyFunction::offsetOfWasmEntryPointCode): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): always start with a dummy - memory, so wasm->wasm calls don't need to null-check - * wasm/js/WebAssemblyMemoryConstructor.cpp: - (JSC::constructJSWebAssemblyMemory): - * wasm/js/WebAssemblyModuleConstructor.cpp: - (JSC::WebAssemblyModuleConstructor::createModule): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - (JSC::WebAssemblyModuleRecord::evaluate): - * wasm/js/WebAssemblyModuleRecord.h: - -2017-01-05 Matthew Hanson - - Merge r210202. rdar://problem/29803676 - - 2016-12-28 Saam Barati - - Unreviewed. Fix jsc.cpp build error. - - * jsc.cpp: - (functionTestWasmModuleFunctions): - -2017-01-05 Matthew Hanson - - Merge r210201. rdar://problem/29803676 - - 2016-12-28 Saam Barati - - WebAssembly: Implement grow_memory and current_memory - https://bugs.webkit.org/show_bug.cgi?id=166448 - - - Reviewed by Keith Miller. - - This patch implements grow_memory, current_memory, and WebAssembly.prototype.grow. - See relevant spec texts here: - - https://github.com/WebAssembly/design/blob/master/Semantics.md#linear-memory-accesses - https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymemoryprototypegrow - - I also fix a couple miscellaneous bugs: - - 1. Data section now understands full init_exprs. - 2. parseVarUint1 no longer has a bug where we allow values larger than 1 if - their bottom 8 bits are zero. - - Since the JS API can now grow memory, we need to make calling an import - and call_indirect refresh the base memory register and the size registers. - - * jsc.cpp: - (functionTestWasmModuleFunctions): - * runtime/Options.h: - * runtime/VM.h: - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::reloadPinnedRegisters): - (JSC::Wasm::B3IRGenerator::emitReloadPinnedRegisters): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmFormat.cpp: - (JSC::Wasm::Segment::create): - * wasm/WasmFormat.h: - (JSC::Wasm::I32InitExpr::I32InitExpr): - (JSC::Wasm::I32InitExpr::globalImport): - (JSC::Wasm::I32InitExpr::constValue): - (JSC::Wasm::I32InitExpr::isConst): - (JSC::Wasm::I32InitExpr::isGlobalImport): - (JSC::Wasm::I32InitExpr::globalImportIndex): - (JSC::Wasm::Segment::byte): - (JSC::Wasm::ModuleInformation::importFunctionCount): - (JSC::Wasm::ModuleInformation::hasMemory): - * wasm/WasmFunctionParser.h: - * wasm/WasmMemory.cpp: - (JSC::Wasm::Memory::Memory): - (JSC::Wasm::Memory::grow): - * wasm/WasmMemory.h: - (JSC::Wasm::Memory::size): - (JSC::Wasm::Memory::sizeInPages): - (JSC::Wasm::Memory::offsetOfMemory): - (JSC::Wasm::Memory::isValid): Deleted. - (JSC::Wasm::Memory::grow): Deleted. - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::makeI32InitExpr): - * wasm/WasmModuleParser.h: - * wasm/WasmPageCount.h: - (JSC::Wasm::PageCount::bytes): - (JSC::Wasm::PageCount::pageCount): - (JSC::Wasm::PageCount::fromBytes): - (JSC::Wasm::PageCount::operator+): - * wasm/WasmParser.h: - (JSC::Wasm::Parser::parseVarUInt1): - * wasm/WasmValidate.cpp: - * wasm/js/JSWebAssemblyInstance.h: - (JSC::JSWebAssemblyInstance::offsetOfMemory): - * wasm/js/JSWebAssemblyMemory.cpp: - (JSC::JSWebAssemblyMemory::~JSWebAssemblyMemory): - (JSC::JSWebAssemblyMemory::grow): - * wasm/js/JSWebAssemblyMemory.h: - (JSC::JSWebAssemblyMemory::offsetOfMemory): - * wasm/js/JSWebAssemblyModule.h: - (JSC::JSWebAssemblyModule::functionImportCount): - (JSC::JSWebAssemblyModule::jsEntrypointCalleeFromFunctionIndexSpace): - (JSC::JSWebAssemblyModule::wasmEntrypointCalleeFromFunctionIndexSpace): - (JSC::JSWebAssemblyModule::importCount): Deleted. - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyMemoryConstructor.cpp: - (JSC::constructJSWebAssemblyMemory): - * wasm/js/WebAssemblyMemoryPrototype.cpp: - (JSC::getMemory): - (JSC::webAssemblyMemoryProtoFuncBuffer): - (JSC::webAssemblyMemoryProtoFuncGrow): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - (JSC::dataSegmentFail): - (JSC::WebAssemblyModuleRecord::evaluate): - * wasm/wasm.json: - -2017-01-05 Matthew Hanson - - Merge r210073. rdar://problem/29762017 - - 2016-12-21 JF Bastien - - WebAssembly JS API: cleanup & pass VM around to {Compile/Runtime}Error - https://bugs.webkit.org/show_bug.cgi?id=166295 - - - Reviewed by Mark Lam. - - Rename the create* functions, and pass VM around, as suggested for - LinkError in #165805. - - At the same time, use the default source appender when - constructing these error types, which gives a nice map back to the - original source as part of the error message. This is clearer when - using the current frame, so add that as well. - - * jit/ThunkGenerators.cpp: - (JSC::throwExceptionFromWasmThunkGenerator): - * wasm/js/JSWebAssemblyCompileError.cpp: - (JSC::JSWebAssemblyCompileError::create): - (JSC::createJSWebAssemblyCompileError): - (JSC::createWebAssemblyCompileError): Deleted. - * wasm/js/JSWebAssemblyCompileError.h: - (JSC::JSWebAssemblyCompileError::create): - * wasm/js/JSWebAssemblyRuntimeError.cpp: - (JSC::JSWebAssemblyRuntimeError::create): - * wasm/js/JSWebAssemblyRuntimeError.h: - (JSC::JSWebAssemblyRuntimeError::create): - * wasm/js/WebAssemblyCompileErrorConstructor.cpp: - (JSC::constructJSWebAssemblyCompileError): - * wasm/js/WebAssemblyModuleConstructor.cpp: - (JSC::WebAssemblyModuleConstructor::createModule): - * wasm/js/WebAssemblyRuntimeErrorConstructor.cpp: - (JSC::constructJSWebAssemblyRuntimeError): - -2017-01-05 Matthew Hanson - - Merge r210244. rdar://problem/29844107 - - 2017-01-03 JF Bastien - - WebAssembly JS API: check and test in-call / out-call values - https://bugs.webkit.org/show_bug.cgi?id=164876 - - - Reviewed by Saam Barati. - - * wasm/WasmBinding.cpp: - (JSC::Wasm::wasmToJs): fix the wasm -> JS call coercions for f32 / - f64 which the assotiated tests inadvertently tripped on: the - previous code wasn't correctly performing JSValue boxing for - "double" values. This change is slightly involved because it - requires two scratch registers to materialize the - `DoubleEncodeOffset` value. This change therefore reorganizes the - code to first generate traps, then handle all integers (freeing - all GPRs), and then all the floating-point values. - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): Implement the defined semantics - for mismatched arities when JS calls wasm: - https://github.com/WebAssembly/design/blob/master/JS.md#exported-function-exotic-objects - - i32 is 0, f32 / f64 are NaN. - - wasm functions which return "void" are "undefined" in JS. - -2017-01-05 Matthew Hanson - - Merge r210228. rdar://problem/29841541 - - 2017-01-02 Saam Barati - - WebAssembly: Some loads don't take into account the offset - https://bugs.webkit.org/show_bug.cgi?id=166616 - - - Reviewed by Keith Miller. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::emitLoadOp): - -2017-01-05 Matthew Hanson - - Merge r210203. rdar://problem/29815000 - - 2016-12-28 Saam Barati - - WebAssembly: Don't allow duplicate export names - https://bugs.webkit.org/show_bug.cgi?id=166490 - - - Reviewed by Keith Miller. - - * wasm/WasmModuleParser.cpp: - -2017-01-05 Matthew Hanson - - Merge r210137. rdar://problem/29760386 - - 2016-12-23 Keith Miller - - WebAssembly: trap on bad division. - https://bugs.webkit.org/show_bug.cgi?id=164786 - - Reviewed by Mark Lam. - - This patch adds traps for division / modulo by zero and for - division by int_min / -1. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::emitChecksForModOrDiv): - * wasm/WasmExceptionType.h: - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::run): - * wasm/wasm.json: - -2017-01-05 Matthew Hanson - - Merge r210127. rdar://problem/29795709 - - 2016-12-22 Keith Miller - - WebAssembly: Make spec-tests/f32.wast.js and spec-tests/f64.wast.js pass - https://bugs.webkit.org/show_bug.cgi?id=166447 - - Reviewed by Saam Barati. - - We needed to treat -0.0 < 0.0 for floating point min/max. For min, - the algorithm works because if a == b then a and b are not NaNs so - either they are the same or they are some zero. When we or a and b - either we get the same number back or we get -0.0. Similarly for - max we use an and and the sign bit gets dropped if one is 0.0 and - the other is -0.0, otherwise, we get the same number back. - - * wasm/wasm.json: - -2017-01-05 Matthew Hanson - - Merge r210126. rdar://problem/29793949 - - 2016-12-22 Saam Barati - - WebAssembly: Make calling Wasm functions that returns or takes an i64 as a parameter an early exception - https://bugs.webkit.org/show_bug.cgi?id=166437 - - - Reviewed by Keith Miller. - - This patch makes it so that we throw an exception before we do - anything else if we call a wasm function that either takes an - i64 as an argument or returns an i64. - - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - (JSC::WebAssemblyFunction::WebAssemblyFunction): - (JSC::WebAssemblyFunction::call): Deleted. - * wasm/js/WebAssemblyFunction.h: - (JSC::WebAssemblyFunction::signatureIndex): - (JSC::WebAssemblyFunction::jsEntrypoint): - -2017-01-05 Matthew Hanson - - Merge r210115. rdar://problem/29793220 - - 2016-12-22 Saam Barati - - WebAssembly: Make the spec-tests/address.wast.js test pass - https://bugs.webkit.org/show_bug.cgi?id=166429 - - - Reviewed by Keith Miller. - - Right now, provably out of bound loads/stores (given a load/store's constant - offset) are not a validation error. However, we were failing to catch uint32_t - overflows in release builds (we did have a debug assertion). To fix this, - I now detect when uint32_t addition will overflow, and instead of emitting - a normal load/store, I emit code that throws an out of bounds memory exception. - - * wasm/WasmB3IRGenerator.cpp: - -2017-01-05 Matthew Hanson - - Merge r210111. rdar://problem/29791695 - - 2016-12-22 Keith Miller - - WebAssembly: The validator should not allow unused stack entries at the end of a block - https://bugs.webkit.org/show_bug.cgi?id=166411 - - Reviewed by Saam Barati. - - This patch also cleans up some of the verbose mode logging. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::dumpExpressionStack): - (JSC::Wasm::B3IRGenerator::dump): - * wasm/WasmFunctionParser.h: - * wasm/WasmValidate.cpp: - (JSC::Wasm::dumpExpressionStack): - (JSC::Wasm::Validate::dump): - -2017-01-05 Matthew Hanson - - Merge r210102. rdar://problem/29784532 - - 2016-12-22 Saam Barati - - WebAssembly: Make the spec-tests/start.wast.js test pass - https://bugs.webkit.org/show_bug.cgi?id=166416 - - - Reviewed by Yusuke Suzuki. - - To make the test run, I had to fix two bugs: - - 1. We weren't properly finding the start function. There was code - that would try to find the start function from the list of *exported* - functions. This is wrong; the start function is an index into the - function index space, which is the space for *imports* and *local* - functions. So the code was just wrong in this respect, and I've - fixed it do the right thing. We weren't sure if this was originally - allowed or not in the spec, but it has been decided that it is allowed - and the spec-tests test for it: https://github.com/WebAssembly/design/issues/896 - - 2. We were emitting a breakpoint for Unreachable. Instead of crashing, - this opcode needs to throw an exception when executing. - - * wasm/WasmB3IRGenerator.cpp: - * wasm/WasmExceptionType.h: - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - (JSC::WebAssemblyModuleRecord::evaluate): - * wasm/js/WebAssemblyModuleRecord.h: - -2017-01-05 Matthew Hanson - - Merge r210091. rdar://problem/29782833 - - 2016-12-21 Keith Miller - - WebAssembly: Fix decode floating point constants in unreachable code - https://bugs.webkit.org/show_bug.cgi?id=166400 - - Reviewed by Saam Barati. - - We decoded these as variable length but they should be fixed length. - - * wasm/WasmFunctionParser.h: - -2017-01-05 Matthew Hanson - - Merge r210090. rdar://problem/29782821 - - 2016-12-21 Keith Miller - - WebAssembly: Allow br, br_if, and br_table to act as a return - https://bugs.webkit.org/show_bug.cgi?id=166393 - - Reviewed by Saam Barati. - - This patch allows br, br_if, and br_table to treat branching to - the size of the control stack to act as a return. This change was - made by adding a new block type to the wasm function parser, - TopLevel. Adding this new block eliminates a lot of the special - case code we had in the parser previously. The only special case - we need is when the end opcode is parsed from the top level. The - B3 IR generator needs to automatically emit a return at that - point. - - Also, this patch adds the function number to validation errors - in the function parser. The current error message is not helpful - otherwise. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::ControlData::dump): - (JSC::Wasm::B3IRGenerator::addTopLevel): - * wasm/WasmFunctionParser.h: - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::parseAndValidateModule): - (JSC::Wasm::Plan::run): - * wasm/WasmValidate.cpp: - (JSC::Wasm::Validate::ControlData::dump): - (JSC::Wasm::Validate::Validate): - (JSC::Wasm::Validate::addTopLevel): - (JSC::Wasm::validateFunction): - -2017-01-05 Matthew Hanson - - Merge r210047. rdar://problem/29758107 - - 2016-12-20 Saam Barati - - WebAssembly: We should compile wasm functions in parallel - https://bugs.webkit.org/show_bug.cgi?id=165993 - - Reviewed by Keith Miller. - - This patch adds a very simple parallel compiler for Wasm code. - This patch speeds up compiling the Unity headless benchmark by - slightly more than 4x on my MBP. To make this safe, I perform - all linking on the main thread. I also had to change some code - inside Wasmb3IRGenerator to be thread safe. - - * b3/air/AirCustom.h: - (JSC::B3::Air::WasmBoundsCheckCustom::generate): - * b3/air/AirGenerationContext.h: - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::B3IRGenerator::emitExceptionCheck): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmB3IRGenerator.h: - * wasm/WasmCallingConvention.h: - (JSC::Wasm::CallingConvention::setupFrameInPrologue): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::parseAndValidateModule): - (JSC::Wasm::Plan::run): - * wasm/WasmPlan.h: - -2017-01-05 Matthew Hanson - - Merge r210038. rdar://problem/29759741 - - 2016-12-20 JF Bastien - - WebAssembly: construct 32-bit encodedJSValue properly - https://bugs.webkit.org/show_bug.cgi?id=166199 - - Reviewed by Mark Lam. - - Constructing an encodedJSValue using `{ }` yields the wrong value - on 32-bit platforms. WebAssembly doesn't currently target 32-bit - platforms, but we may as well get it right. - - * wasm/JSWebAssembly.cpp: - (JSC::webAssemblyCompileFunc): - (JSC::webAssemblyValidateFunc): - * wasm/js/JSWebAssemblyHelpers.h: - (JSC::toNonWrappingUint32): - * wasm/js/WebAssemblyCompileErrorConstructor.cpp: - (JSC::constructJSWebAssemblyCompileError): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyMemoryConstructor.cpp: - (JSC::constructJSWebAssemblyMemory): - * wasm/js/WebAssemblyModuleConstructor.cpp: - (JSC::constructJSWebAssemblyModule): - * wasm/js/WebAssemblyRuntimeErrorConstructor.cpp: - (JSC::constructJSWebAssemblyRuntimeError): - * wasm/js/WebAssemblyTableConstructor.cpp: - (JSC::constructJSWebAssemblyTable): - * wasm/js/WebAssemblyTablePrototype.cpp: - (JSC::webAssemblyTableProtoFuncLength): - (JSC::webAssemblyTableProtoFuncGrow): - (JSC::webAssemblyTableProtoFuncGet): - (JSC::webAssemblyTableProtoFuncSet): - -2017-01-05 Matthew Hanson - - Merge r210026. rdar://problem/29735737 - - 2016-12-20 JF Bastien - - WebAssembly: unique function signatures - https://bugs.webkit.org/show_bug.cgi?id=165957 - - - Reviewed by Saam Barati. - - Signatures in a Module's Type section can be duplicated, we - therefore need to unique them so that call_indirect only needs to - do a single integer compare to check that a callee's Signature is - the same as the Signature declared at the call site. Without - uniquing we'd either trap when duplicate Signatures are used, or - we'd need to do multiple comparisons. This patch makes that narrow - usecase function correctly. - - There's further complication when calling from wasm to - wasm, in which case the Signatures must also match. Such - cross-instance calls will be improved in bug #165282, but this - patch sets the groundwork for it: - - - Signatures are now owned by SignatureInformation which lives on - VM, and is shared by all Modules. - - When parsing a Module, a Signature is created for every Type - entry, and then uniqued by SignatureInformation's adopt - method. Duplicate Signatures are dropped and the previous - SignatureIndex is returned, new Signatures are adopted and a new - SignatureIndex is created. - - The SignatureIndex values are monotonic. 0 is used to represent - invalid indices, which trap. This can only occur through Table. - - SignatureInformation is used while generating code to map a - SignatureIndex back to the Signature* when return / argument - information is needed. This is a simple lookup into a Vector. It - isn't used at runtime. - - These Signatures live forever on VM because the bookkeeping - likely isn't worth it. We may want to empty things out if all - Modules die, this is tracked in bug #166037. - - We can further improve things by bit-packing SignatureIndex with - Code*, which is tracked by bug #165511. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * runtime/VM.h: wasm signatures are uniqued here, but aren't accessed frequently (only during parsing) so indirection is fine - * wasm/WasmB3IRGenerator.cpp: use SignatureIndex instead of Signature* when appropriate, and when still using Signature* do so with its new API - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmBinding.cpp: - (JSC::Wasm::importStubGenerator): use SignatureIndex - * wasm/WasmBinding.h: - * wasm/WasmCallingConvention.h: - (JSC::Wasm::CallingConvention::loadArguments): - * wasm/WasmFormat.cpp: drive-by move of alloc/free functions to the implementation file, allows the .h file to drop an FastMalloc.h - (JSC::Wasm::Segment::create): - (JSC::Wasm::Segment::destroy): - (JSC::Wasm::Segment::createPtr): - * wasm/WasmFormat.h: move Signature to its own file - (JSC::Wasm::CallableFunction::CallableFunction): - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::FunctionParser): - * wasm/WasmModuleParser.cpp: - * wasm/WasmModuleParser.h: - (JSC::Wasm::ModuleParser::ModuleParser): - * wasm/WasmParser.h: - (JSC::Wasm::Parser::Parser): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::parseAndValidateModule): - (JSC::Wasm::Plan::run): - * wasm/WasmSignature.cpp: Added. - (JSC::Wasm::Signature::dump): - (JSC::Wasm::Signature::hash): - (JSC::Wasm::Signature::create): - (JSC::Wasm::Signature::createInvalid): - (JSC::Wasm::Signature::destroy): - (JSC::Wasm::SignatureInformation::~SignatureInformation): - (JSC::Wasm::SignatureInformation::adopt): - (JSC::Wasm::SignatureInformation::get): - * wasm/WasmSignature.h: Added. - (JSC::Wasm::Signature::Signature): - (JSC::Wasm::Signature::storage): - (JSC::Wasm::Signature::allocatedSize): - (JSC::Wasm::Signature::returnType): - (JSC::Wasm::Signature::returnCount): - (JSC::Wasm::Signature::argumentCount): - (JSC::Wasm::Signature::argument): - (JSC::Wasm::Signature::operator==): - (JSC::Wasm::SignatureHash::empty): - (JSC::Wasm::SignatureHash::deleted): - (JSC::Wasm::SignatureHash::SignatureHash): - (JSC::Wasm::SignatureHash::operator==): - (JSC::Wasm::SignatureHash::equal): - (JSC::Wasm::SignatureHash::hash): - (JSC::Wasm::SignatureHash::isHashTableDeletedValue): - * wasm/WasmValidate.cpp: - (JSC::Wasm::validateFunction): - * wasm/WasmValidate.h: - * wasm/js/JSWebAssemblyInstance.cpp: - (JSC::JSWebAssemblyInstance::create): - * wasm/js/JSWebAssemblyModule.h: - (JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace): - * wasm/js/JSWebAssemblyTable.cpp: - (JSC::JSWebAssemblyTable::JSWebAssemblyTable): - (JSC::JSWebAssemblyTable::clearFunction): - (JSC::JSWebAssemblyTable::setFunction): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - (JSC::WebAssemblyFunction::call): - (JSC::WebAssemblyFunction::create): - (JSC::WebAssemblyFunction::WebAssemblyFunction): - (JSC::WebAssemblyFunction::finishCreation): - * wasm/js/WebAssemblyFunction.h: - (JSC::WebAssemblyFunction::signatureIndex): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - (JSC::WebAssemblyModuleRecord::evaluate): - -2017-01-05 Matthew Hanson - - Merge r209979. rdar://problem/29735737 - - 2016-12-18 Saam Barati - - WebAssembly: Implement the WebAssembly.compile and WebAssembly.validate - https://bugs.webkit.org/show_bug.cgi?id=165936 - - Reviewed by Mark Lam. - - The APIs are documented here: - - https://github.com/WebAssembly/design/blob/master/JS.md#webassemblycompile - - https://github.com/WebAssembly/design/blob/master/JS.md#webassemblyvalidate - - * wasm/JSWebAssembly.cpp: - (JSC::webAssemblyCompileFunc): - (JSC::webAssemblyValidateFunc): - (JSC::JSWebAssembly::finishCreation): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::parseAndValidateModule): - (JSC::Wasm::Plan::run): - * wasm/WasmPlan.h: - * wasm/js/JSWebAssemblyHelpers.h: - (JSC::getWasmBufferFromValue): - * wasm/js/WebAssemblyModuleConstructor.cpp: - (JSC::constructJSWebAssemblyModule): - (JSC::callJSWebAssemblyModule): - (JSC::WebAssemblyModuleConstructor::createModule): - * wasm/js/WebAssemblyModuleConstructor.h: - -2017-01-05 Matthew Hanson - - Merge r210359. rdar://problem/29882478 - - 2017-01-05 Per Arne Vollan - - [Win] Compile error. - https://bugs.webkit.org/show_bug.cgi?id=166726 - - Reviewed by Alex Christensen. - - Add include folder. - - * CMakeLists.txt: - -2017-01-05 Matthew Hanson - - Merge r210028. rdar://problem/29747874 - - 2016-12-20 JF Bastien - - WebAssembly API: implement WebAssembly.LinkError - https://bugs.webkit.org/show_bug.cgi?id=165805 - - - Reviewed by Mark Lam. - - As described here: https://github.com/WebAssembly/design/pull/901 - Some TypeError and RangeError are now converted to WebAssembly.LinkError. - - * CMakeLists.txt: add files - * DerivedSources.make: add autoget .lut.h files - * JavaScriptCore.xcodeproj/project.pbxproj: add files - * builtins/BuiltinNames.h: new name LinkError - * runtime/JSGlobalObject.h: auto-register LinkError using existing macro magic - * wasm/JSWebAssembly.h: make the new includes available - * wasm/js/JSWebAssemblyLinkError.cpp: Copied from Source/JavaScriptCore/wasm/JSWebAssemblyCompileError.cpp. - (JSC::JSWebAssemblyLinkError::create): - (JSC::JSWebAssemblyLinkError::JSWebAssemblyLinkError): - (JSC::createWebAssemblyLinkError): - * wasm/js/JSWebAssemblyLinkError.h: Copied from Source/JavaScriptCore/wasm/JSWebAssemblyCompileError.h. - (JSC::JSWebAssemblyLinkError::create): - * wasm/js/WebAssemblyInstanceConstructor.cpp: update as per spec change - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyLinkErrorConstructor.cpp: Copied from Source/JavaScriptCore/wasm/WebAssemblyCompileErrorConstructor.cpp. - (JSC::constructJSWebAssemblyLinkError): - (JSC::callJSWebAssemblyLinkError): - (JSC::WebAssemblyLinkErrorConstructor::create): - (JSC::WebAssemblyLinkErrorConstructor::createStructure): - (JSC::WebAssemblyLinkErrorConstructor::finishCreation): - (JSC::WebAssemblyLinkErrorConstructor::WebAssemblyLinkErrorConstructor): - (JSC::WebAssemblyLinkErrorConstructor::getConstructData): - (JSC::WebAssemblyLinkErrorConstructor::getCallData): - * wasm/js/WebAssemblyLinkErrorConstructor.h: Copied from Source/JavaScriptCore/wasm/WebAssemblyCompileErrorConstructor.h. - * wasm/js/WebAssemblyLinkErrorPrototype.cpp: Copied from Source/JavaScriptCore/wasm/WebAssemblyCompileErrorPrototypr.cpp. - (JSC::WebAssemblyLinkErrorPrototype::create): - (JSC::WebAssemblyLinkErrorPrototype::createStructure): - (JSC::WebAssemblyLinkErrorPrototype::finishCreation): - (JSC::WebAssemblyLinkErrorPrototype::WebAssemblyLinkErrorPrototype): - * wasm/js/WebAssemblyLinkErrorPrototype.h: Copied from Source/JavaScriptCore/wasm/WebAssemblyCompileErrorPrototypr.h. - * wasm/js/WebAssemblyModuleRecord.cpp: update as per spec change - (JSC::dataSegmentFail): - (JSC::WebAssemblyModuleRecord::evaluate): - -2017-01-05 Matthew Hanson - - Merge r209998. rdar://problem/29554366 - - 2016-12-19 Joseph Pecoraro - - Web Inspector: Assertion seen in InspectorDebuggerAgent::refAsyncCallData with Inspector open - https://bugs.webkit.org/show_bug.cgi?id=166034 - - - Reviewed by Brian Burg. - - * inspector/agents/InspectorDebuggerAgent.cpp: - (Inspector::InspectorDebuggerAgent::refAsyncCallData): - Remove assertion. This assert can happen if the currently executing callback - was just explicitly cancelled by script. Existing code already handles if - no async data was found for the given identifier. - -2016-12-19 Babak Shafiei - - Merge r210010. - - 2016-12-19 Mark Lam - - Rolling out r209974 and r209952. They break some websites in mysterious ways. Step 2: Rollout r209952. - https://bugs.webkit.org/show_bug.cgi?id=166049 - - Not reviewed. - - * bytecode/HandlerInfo.h: - (JSC::HandlerInfoBase::typeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::generate): - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::emitReturn): - (JSC::BytecodeGenerator::pushFinallyControlFlowScope): - (JSC::BytecodeGenerator::pushIteratorCloseControlFlowScope): - (JSC::BytecodeGenerator::popFinallyControlFlowScope): - (JSC::BytecodeGenerator::popIteratorCloseControlFlowScope): - (JSC::BytecodeGenerator::emitComplexPopScopes): - (JSC::BytecodeGenerator::emitPopScopes): - (JSC::BytecodeGenerator::pushTry): - (JSC::BytecodeGenerator::popTryAndEmitCatch): - (JSC::BytecodeGenerator::labelScopeDepth): - (JSC::BytecodeGenerator::pushLocalControlFlowScope): - (JSC::BytecodeGenerator::popLocalControlFlowScope): - (JSC::BytecodeGenerator::emitEnumeration): - (JSC::BytecodeGenerator::emitYield): - (JSC::BytecodeGenerator::emitDelegateYield): - (JSC::BytecodeGenerator::popTry): Deleted. - (JSC::BytecodeGenerator::emitCatch): Deleted. - (JSC::BytecodeGenerator::restoreScopeRegister): Deleted. - (JSC::BytecodeGenerator::labelScopeDepthToLexicalScopeIndex): Deleted. - (JSC::BytecodeGenerator::emitIsNumber): Deleted. - (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded): Deleted. - (JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded): Deleted. - (JSC::BytecodeGenerator::emitFinallyCompletion): Deleted. - (JSC::BytecodeGenerator::allocateFinallyRegisters): Deleted. - (JSC::BytecodeGenerator::releaseFinallyRegisters): Deleted. - (JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf): Deleted. - * bytecompiler/BytecodeGenerator.h: - (JSC::BytecodeGenerator::isInFinallyBlock): - (JSC::FinallyJump::FinallyJump): Deleted. - (JSC::FinallyContext::FinallyContext): Deleted. - (JSC::FinallyContext::outerContext): Deleted. - (JSC::FinallyContext::finallyLabel): Deleted. - (JSC::FinallyContext::depth): Deleted. - (JSC::FinallyContext::numberOfBreaksOrContinues): Deleted. - (JSC::FinallyContext::incNumberOfBreaksOrContinues): Deleted. - (JSC::FinallyContext::handlesReturns): Deleted. - (JSC::FinallyContext::setHandlesReturns): Deleted. - (JSC::FinallyContext::registerJump): Deleted. - (JSC::FinallyContext::numberOfJumps): Deleted. - (JSC::FinallyContext::jumps): Deleted. - (JSC::ControlFlowScope::ControlFlowScope): Deleted. - (JSC::ControlFlowScope::isLabelScope): Deleted. - (JSC::ControlFlowScope::isFinallyScope): Deleted. - (JSC::BytecodeGenerator::currentLexicalScopeIndex): Deleted. - (JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope): Deleted. - (JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope): Deleted. - (JSC::BytecodeGenerator::finallyActionRegister): Deleted. - (JSC::BytecodeGenerator::finallyReturnValueRegister): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyActionToJumpID): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow): Deleted. - (JSC::BytecodeGenerator::bytecodeOffsetToJumpID): Deleted. - * bytecompiler/NodesCodegen.cpp: - (JSC::ContinueNode::emitBytecode): - (JSC::BreakNode::emitBytecode): - (JSC::ReturnNode::emitBytecode): - (JSC::TryNode::emitBytecode): - -2016-12-19 Babak Shafiei - - Merge r210007. - - 2016-12-19 Mark Lam - - Rolling out r209974 and r209952. They break some websites in mysterious ways. Step 1: Rollout r209974. - https://bugs.webkit.org/show_bug.cgi?id=166049 - - Not reviewed. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitEnumeration): - (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded): - (JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded): - (JSC::BytecodeGenerator::emitFinallyCompletion): - (JSC::BytecodeGenerator::allocateFinallyRegisters): - (JSC::BytecodeGenerator::releaseFinallyRegisters): - (JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf): - (JSC::BytecodeGenerator::allocateCompletionRecordRegisters): Deleted. - (JSC::BytecodeGenerator::releaseCompletionRecordRegisters): Deleted. - (JSC::BytecodeGenerator::emitJumpIfCompletionType): Deleted. - * bytecompiler/BytecodeGenerator.h: - (JSC::FinallyJump::FinallyJump): - (JSC::FinallyContext::registerJump): - (JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope): - (JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope): - (JSC::BytecodeGenerator::finallyActionRegister): - (JSC::BytecodeGenerator::finallyReturnValueRegister): - (JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion): - (JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion): - (JSC::BytecodeGenerator::emitSetFinallyActionToJumpID): - (JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion): - (JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow): - (JSC::BytecodeGenerator::bytecodeOffsetToJumpID): - (JSC::bytecodeOffsetToJumpID): Deleted. - (JSC::BytecodeGenerator::CompletionRecordScope::CompletionRecordScope): Deleted. - (JSC::BytecodeGenerator::CompletionRecordScope::~CompletionRecordScope): Deleted. - (JSC::BytecodeGenerator::completionTypeRegister): Deleted. - (JSC::BytecodeGenerator::completionValueRegister): Deleted. - (JSC::BytecodeGenerator::emitSetCompletionType): Deleted. - (JSC::BytecodeGenerator::emitSetCompletionValue): Deleted. - * bytecompiler/NodesCodegen.cpp: - (JSC::TryNode::emitBytecode): - -2016-12-19 Dean Jackson - - Merge another patch for rdar://problem/29466493. - - 2016-12-19 Dean Jackson - - Disable some features on the safari-603-branch. - + Disable some features on this release branch. + * Configurations/FeatureDefines.xcconfig: + * runtime/Options.h: -2016-12-19 Babak Shafiei +2017-07-17 Saam Barati - Merge patch for rdar://problem/29466493. + Remove custom defined RELEASE_ASSERT in DFGObjectAllocationSinkingPhase + https://bugs.webkit.org/show_bug.cgi?id=174584 - 2016-12-19 Dean Jackson + Rubber stamped by Keith Miller. - Disable some features on the safari-603-branch. - + I used it to diagnose a bug. The bug is now fixed. This custom + RELEASE_ASSERT is no longer needed. - - Force the default state of experimental features to off. - - Move some experimental features that should be enabled on this - branch into the general feature list, so they can't be disabled. - - Disable some features that are not ready. + * dfg/DFGObjectAllocationSinkingPhase.cpp: - * Configurations/FeatureDefines.xcconfig: +2017-07-17 Michael Catanzaro -2016-12-18 Mark Lam - - Rename finallyActionRegister to completionTypeRegister and only store int JSValues in it. - https://bugs.webkit.org/show_bug.cgi?id=165979 - - Reviewed by Saam Barati. - - This patch makes it so that we only store int JSValues in the finallyActionRegister - thereby making type prediction on this register more successful for JITs. In so - doing, we are able to get some additional benefits: - - 1. Renamed the following: - FinallyRegistersScope => CompletionRecordScope - finallyActionRegister => completionTypeRegister - finallyReturnValueRegister => completionValueRegister - - These new names are more in line with the ES spec, which describes these - values as the completion record and its type and value properties. - https://tc39.github.io/ecma262/#sec-completion-record-specification-type - - 2. We now think of the Break and Continue jumpIDs as encodings of CompletionType - (in our implementation of completion type). As a result, we only need one of - each of the emitter methods for getting, setting, and compare-and-jump on the - completion type. The code using these methods also reads much clearer now. - - 3. Finally blocks' op_catch should now always pop the caught Exception object into - the completionValueRegister instead of the completionTypeRegister (formerly - finallyActionRegister). - - Also removed the restoreScopeRegister() call in the IteratorClose catch block - because that is an implementation specific synthesized catch block, and we - can guarantee that it never needs to resolve any symbols from the scope. Hence, - there is no need to restore the scope register. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitEnumeration): - (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded): - (JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded): - (JSC::BytecodeGenerator::emitFinallyCompletion): - (JSC::BytecodeGenerator::allocateCompletionRecordRegisters): - (JSC::BytecodeGenerator::releaseCompletionRecordRegisters): - (JSC::BytecodeGenerator::emitJumpIfCompletionType): - (JSC::BytecodeGenerator::allocateFinallyRegisters): Deleted. - (JSC::BytecodeGenerator::releaseFinallyRegisters): Deleted. - (JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf): Deleted. - * bytecompiler/BytecodeGenerator.h: - (JSC::bytecodeOffsetToJumpID): - (JSC::FinallyJump::FinallyJump): - (JSC::FinallyContext::registerJump): - (JSC::BytecodeGenerator::CompletionRecordScope::CompletionRecordScope): - (JSC::BytecodeGenerator::CompletionRecordScope::~CompletionRecordScope): - (JSC::BytecodeGenerator::completionTypeRegister): - (JSC::BytecodeGenerator::completionValueRegister): - (JSC::BytecodeGenerator::emitSetCompletionType): - (JSC::BytecodeGenerator::emitSetCompletionValue): - (JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope): Deleted. - (JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope): Deleted. - (JSC::BytecodeGenerator::finallyActionRegister): Deleted. - (JSC::BytecodeGenerator::finallyReturnValueRegister): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyActionToJumpID): Deleted. - (JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion): Deleted. - (JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow): Deleted. - (JSC::BytecodeGenerator::bytecodeOffsetToJumpID): Deleted. - * bytecompiler/NodesCodegen.cpp: - (JSC::TryNode::emitBytecode): - -2016-12-17 Saam Barati - - WebAssembly: WasmB3IRGenerator uses WarmAny as a ValueRep but expects the incoming value to be a register - https://bugs.webkit.org/show_bug.cgi?id=165989 - - Reviewed by Mark Lam. - - The input should be constrained to a register to match what - the patchpoint code expects. - - * wasm/WasmB3IRGenerator.cpp: - -2016-12-17 Saam Barati - - WebAssembly: Change a RELEASE_ASSERT_NOT_REACHED to a jit.breakpoint() for now to allow us to run some wasm benchmarks - https://bugs.webkit.org/show_bug.cgi?id=165990 - - Reviewed by Mark Lam. - - * wasm/WasmBinding.cpp: - (JSC::Wasm::importStubGenerator): - -2016-12-16 Joseph Pecoraro - - JSContext Inspector: Avoid some possible exceptions inspecting a JSContext - https://bugs.webkit.org/show_bug.cgi?id=165986 - - - Reviewed by Matt Baker. - - * inspector/InjectedScriptSource.js: - (InjectedScript.prototype.processProperties): - Prefer String.prototype.endsWith now that it is available. - - (InjectedScript.prototype._describe): - Prefer Function.prototype.toString for converting functions to String. - Previously we were doing String(f) which would to Symbol.toPrimitive - conversion which seems unnecessary here. - -2016-12-16 Michael Catanzaro - - Unreviewed, fix GCC 6 build failure after r209952 - - Return false, not nullptr, in function returning bool. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded): - -2016-12-16 Saam Barati - - WebAssembly: We still have some incorrect parsing productions inside unreachable code - https://bugs.webkit.org/show_bug.cgi?id=165981 - - Reviewed by Keith Miller. - - This hardens our parsing for CallIndirect and Loop/Block/If to be exactly like their reachable variant. - - It also fixes a more nefarious bug in which we were decoding an extra varuint32 - for Br/BrIf inside unreachable code. - - * wasm/WasmFunctionParser.h: - -2016-12-16 Filip Pizlo - - CellState should have members with accurate names - https://bugs.webkit.org/show_bug.cgi?id=165969 - - Reviewed by Mark Lam. - - This once again renames the members in CellState. I wanted to convey the following - pieces of information in the names: - - - What does the state mean for Generational GC? - - What does the state mean for Concurrent GC? - - Does the state guarantee what it means, or is there some contingency? - - The names I came up with are: - - PossiblyOldOrBlack: An object in this state may be old, or may be black, depending on - other things. If the mark bit is set then the object is either black or being - blackened as we speak. It's going to survive the GC, so it will be old, but may be - new now. In between GCs, objects in this state are definitely old. If the mark bit - is not set, then the object is actually old and white. - - DefinitelyNewAndWhite: The object was just allocated so it is white (not marked) and - new. - - DefinitelyGrey: The object is definitely grey - it will be rescanned in the future. It - may be new or old depending on other things. - - * heap/CellState.h: - * heap/Heap.cpp: - (JSC::Heap::addToRememberedSet): - (JSC::Heap::writeBarrierSlowPath): - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::appendJSCellOrAuxiliary): - (JSC::SlotVisitor::setMarkedAndAppendToMarkStack): - (JSC::SlotVisitor::appendToMarkStack): - (JSC::SlotVisitor::visitChildren): - * runtime/JSCellInlines.h: - (JSC::JSCell::JSCell): - * runtime/StructureIDBlob.h: - (JSC::StructureIDBlob::StructureIDBlob): - -2016-12-16 Saam Barati - - B3::DoubleToFloatReduction will accidentally convince itself it converted a Phi from Double to Float and then convert uses of that Phi into a use of FloatToDouble(@Phi) - https://bugs.webkit.org/show_bug.cgi?id=165946 - - Reviewed by Keith Miller. - - This was happening because the phase will convert some Phi nodes - from Double to Float. However, one place that did this conversion - forgot to first check if the Phi was already a Float. If it's already - a Float, a later part of the phase will be buggy if the phase claims that it has - converted it from Double->Float. The reason is that at the end of the - phase, we'll look for all uses of former Double Phi nodes and make them - be a use of ConvertFloatToDouble on the Phi, instead of a use of the Phi itself. - This is clearly wrong if the Phi were Float to begin with (and - therefore, the uses were Float uses to begin with). - - * b3/B3ReduceDoubleToFloat.cpp: - * b3/testb3.cpp: - (JSC::B3::testReduceFloatToDoubleValidates): - (JSC::B3::run): - -2016-12-16 Mark Lam - - De-duplicate finally blocks. - https://bugs.webkit.org/show_bug.cgi?id=160168 - - Reviewed by Keith Miller. - - JS execution can arrive at a finally block when there are abrupt completions from - its try or catch block. The abrupt completion types include Break, - Continue, Return, and Throw. The non-abrupt completion type is called Normal - (i.e. the case of a try block falling through to the finally block). - - Previously, we enable each of these paths for abrupt completion (except for Throw) - to run the finally block code by duplicating the finally block code at each of - the sites that trigger those completions. This patch fixes the implementation so - that each of these abrupt completions will set a finallyActionRegister (plus a - finallyReturnValueRegister for CompletionType::Return) and then jump to the - relevant finally blocks, and continue to thread through subsequent outer finally - blocks until execution reaches the outermost finally block that the completion - type dictates. We no longer duplicate the finally block code. - - The implementation details: - 1. We allocate a pair of finallyActionRegister and finallyReturnValueRegister - just before entering the outermost try-catch-finally scope. - - On allocating the registers, we set them to the empty JSValue. This serves - to set the completion type to CompletionType::Normal (see (2) below). - - 2. The finallyActionRegister serves 2 purpose: - a. indicates the CompletionType that triggered entry into the finally block. - - This is how we encode the completion type in the finallyActionRegister: - 1. CompletionType::Normal - - finallyActionRegister is set to the empty JSValue. - 2. CompletionType::Break - - finallyActionRegister is set to the int jumpID for the site of the break statement. - 3. CompletionType::Continue - - finallyActionRegister is set to the int jumpID for the site of the continue statement. - 4. CompletionType::Return - - finallyActionRegister is set to CompletionType::Return as an int JSValue. - - finallyReturnValueRegister is set to the value to be returned. - 5. CompletionType::Throw - - finallyActionRegister is set to the exception object that was caught by the finally block. - - Hence, if the finallyActionRegister can either be: - 1. empty i.e. we're handling CompletionType::Normal. - 2. an int JSValue i.e. we're handling CompletionType::Break, Continue, or Return. - 3. an object i.e. we're handling CompletionType::Throw. - - b. stores the exception caught in the finally block if we're handing - CompletionType::Throw. - - 3. Each finally block will have 2 entries: - a. the entry via throw. - b. the normal entry. - - The entry via throw is recorded in the codeBlock's exception table, and can - only be jumped to by the VM's exception handling mechanism. - - The normal entry is recorded in a FinallyContext (at bytecode generation time - only) and is jumped to when we want enter the finally block due any of the - other CompletionTypes. - - 4. CompletionType::Normal - ====================== - We encounter this when falling through from a try or catch block to the finally block. - - For the try block case, since finallyActionRegister is set to Normal by default, - there's nothing more that needs to be done. - - For the catch block case, since we entered the catch block with an exception, - finallyActionRegister may be set to Throw. We'll need to set it to Normal - before jumping to the finally block's normal entry. - - CompletionType::Break - ===================== - When we emit bytecode for the BreakNode, we check if we have any FinallyContexts - that we need to service before jumping to the breakTarget. If we do, then: - a. we'll register a jumpID along with the breakTarget with the outermost FinallyContext. - b. we'll also increment the numberOfBreaksOrContinues count in each FinallyContext - from the innermost to the outermost. - c. instead of emitting bytecode to jump to the breakTarget, we: - 1. emit bytecode to set finallyActionRegister to the jumpID. - b. emit bytecode to jump to the normal entry of the innermost finally block. - - Each finally block will take care of cascading to the next outer finally block - as needed (see (5) below). - - CompletionType::Continue - ======================== - Since continues and breaks work the same way (i.e. with a jump), we handle this - exactly the same way as CompletionType::Break, except that we use the - continueTarget instead of the breakTarget. - - CompletionType::Return - ====================== - When we emit bytecode for the ReturnNode, we check if we have any FinallyContexts - at all on the m_controlFlowScopeStack. - - If so, then instead of emitting op_ret, we: - 1. emit bytecode to set finallyActionRegister to the CompletionType::Return. - 1. emit bytecode to move the return value into finallyReturnValueRegister. - 2. emit bytecode to jump to the normal entry of the innermost finally block. - - Each finally block will take care of cascading to the next outer finally block - as needed (see (5) below). - - CompletionType::Throw - ====================== - The op_catch of a finally block will always store the caught exception object - in the finallyActionRegister. This means we're handling CompletionType::Throw - (see (2) above). - - 5. What happens in each finally block? - ================================== - Only the finally block's entry via throw will have an op_catch that catches the - pending exception (and stores it in the finallyActionRegister). This throw - entry then falls through to the normal entry. - - The finally block's normal entry will restore the scope of the finally block - and proceed to execute its code. - - At the end of the finally block (see emitFinallyCompletion()), the finally - block will check the finallyActionRegister for each completion type in the - following order: - - a. CompletionType::Normal: jump to the code after the finally block as - designated by a normalCompletion label. - - b. CompletionType::Break and Continue: - If the FinallyContext for this block has registered FinallyJumps, we'll - check for the jumpIDs against the finallyActionRegister. If the jumpID - matches, jump to the corresponding jumpTarget. - - If no jumpIDs match but the FinallyContext's numberOfBreaksOrContinues is - greater than the number of registered FinallyJumps, then this means that - we have a Break or Continue that needs to be handled by an outer finally - block. In that case, jump to the outer finally block's normal entry. - - c. CompletionType::Return: - If this finally block is not the outermost and finallyActionRegister contains - CompletionType::Return, then jump to the outer finally block's normal entry. - - Otherwise, if this finally block is the outermost and finallyActionRegister - contains CompletionType::Return, then execute op_ret and return the value - in finallyReturnValueRegister. - - d. CompletionType::Throw: - If we're not handling any of the above cases, then just throw the - finallyActionRegister which contains the exception to re-throw. - - 6. restoreScopeRegister() - - Since the needed scope objects are always stored in a local, we can restore - the scope register by simply moving from that local instead of going through - op_get_parent_scope. - - 7. m_controlFlowScopeStack needs to be a SegmentedVector instead of a Vector. - This makes it easier to keep a pointer to the FinallyContext on that stack, - and not have to worry about the vector being realloc'ed due to resizing. - - Performance appears to be neutral both on ES6SampleBench (run via cli) and the - JSC benchmarks. - - Relevant spec references: - https://tc39.github.io/ecma262/#sec-completion-record-specification-type - https://tc39.github.io/ecma262/#sec-try-statement-runtime-semantics-evaluation - - * bytecode/HandlerInfo.h: - (JSC::HandlerInfoBase::typeName): - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::generate): - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::emitReturn): - (JSC::BytecodeGenerator::pushFinallyControlFlowScope): - (JSC::BytecodeGenerator::popFinallyControlFlowScope): - (JSC::BytecodeGenerator::allocateAndEmitScope): - (JSC::BytecodeGenerator::pushTry): - (JSC::BytecodeGenerator::popTry): - (JSC::BytecodeGenerator::emitCatch): - (JSC::BytecodeGenerator::restoreScopeRegister): - (JSC::BytecodeGenerator::labelScopeDepthToLexicalScopeIndex): - (JSC::BytecodeGenerator::labelScopeDepth): - (JSC::BytecodeGenerator::pushLocalControlFlowScope): - (JSC::BytecodeGenerator::popLocalControlFlowScope): - (JSC::BytecodeGenerator::emitEnumeration): - (JSC::BytecodeGenerator::emitIsNumber): - (JSC::BytecodeGenerator::emitYield): - (JSC::BytecodeGenerator::emitDelegateYield): - (JSC::BytecodeGenerator::emitJumpViaFinallyIfNeeded): - (JSC::BytecodeGenerator::emitReturnViaFinallyIfNeeded): - (JSC::BytecodeGenerator::emitFinallyCompletion): - (JSC::BytecodeGenerator::allocateFinallyRegisters): - (JSC::BytecodeGenerator::releaseFinallyRegisters): - (JSC::BytecodeGenerator::emitCompareFinallyActionAndJumpIf): - (JSC::BytecodeGenerator::pushIteratorCloseControlFlowScope): Deleted. - (JSC::BytecodeGenerator::popIteratorCloseControlFlowScope): Deleted. - (JSC::BytecodeGenerator::emitComplexPopScopes): Deleted. - (JSC::BytecodeGenerator::emitPopScopes): Deleted. - (JSC::BytecodeGenerator::popTryAndEmitCatch): Deleted. - * bytecompiler/BytecodeGenerator.h: - (JSC::FinallyJump::FinallyJump): - (JSC::FinallyContext::FinallyContext): - (JSC::FinallyContext::outerContext): - (JSC::FinallyContext::finallyLabel): - (JSC::FinallyContext::depth): - (JSC::FinallyContext::numberOfBreaksOrContinues): - (JSC::FinallyContext::incNumberOfBreaksOrContinues): - (JSC::FinallyContext::handlesReturns): - (JSC::FinallyContext::setHandlesReturns): - (JSC::FinallyContext::registerJump): - (JSC::FinallyContext::numberOfJumps): - (JSC::FinallyContext::jumps): - (JSC::ControlFlowScope::ControlFlowScope): - (JSC::ControlFlowScope::isLabelScope): - (JSC::ControlFlowScope::isFinallyScope): - (JSC::BytecodeGenerator::currentLexicalScopeIndex): - (JSC::BytecodeGenerator::FinallyRegistersScope::FinallyRegistersScope): - (JSC::BytecodeGenerator::FinallyRegistersScope::~FinallyRegistersScope): - (JSC::BytecodeGenerator::finallyActionRegister): - (JSC::BytecodeGenerator::finallyReturnValueRegister): - (JSC::BytecodeGenerator::emitSetFinallyActionToNormalCompletion): - (JSC::BytecodeGenerator::emitSetFinallyActionToReturnCompletion): - (JSC::BytecodeGenerator::emitSetFinallyActionToJumpID): - (JSC::BytecodeGenerator::emitSetFinallyReturnValueRegister): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNormalCompletion): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotJump): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsReturnCompletion): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotReturnCompletion): - (JSC::BytecodeGenerator::emitJumpIfFinallyActionIsNotThrowCompletion): - (JSC::BytecodeGenerator::emitJumpIfCompletionTypeIsThrow): - (JSC::BytecodeGenerator::bytecodeOffsetToJumpID): - (JSC::BytecodeGenerator::isInFinallyBlock): Deleted. - * bytecompiler/NodesCodegen.cpp: - (JSC::ContinueNode::emitBytecode): - (JSC::BreakNode::emitBytecode): - (JSC::ReturnNode::emitBytecode): - (JSC::TryNode::emitBytecode): - -2016-12-16 Keith Miller - - Add missing cases to parseUnreachableExpression and cleanup FunctionParser - https://bugs.webkit.org/show_bug.cgi?id=165966 - - Reviewed by Saam Barati. - - This patch adds a number of missing cases to the Wasm FunctionParser's unreachable - code decoder. It also, removes unneeded OpType namespaces where they were not - needed and has the unary / binary macros cover all the cases rather than - just the simple cases. - - * wasm/WasmFunctionParser.h: - -2016-12-16 Mark Lam - - Add predecessor info to dumps from JSC_dumpBytecodeLivenessResults=true. - https://bugs.webkit.org/show_bug.cgi?id=165958 - - Reviewed by Saam Barati. - - Also: - 1. refactored the code to use a common lambda function to dump FastBitVectors. - 2. list successors by their block index instead of pointers. - - * bytecode/BytecodeLivenessAnalysis.cpp: - (JSC::BytecodeLivenessAnalysis::dumpResults): - -2016-12-16 Saam Barati - - WebAssembly: WasmB3IRGenerator should throw exceptions instead of crash - https://bugs.webkit.org/show_bug.cgi?id=165834 - - Reviewed by Keith Miller. - - This patch generalizes how we throw exceptions in the Wasm::B3IRGenerator. - There are still places where we need to throw exceptions and we don't, but - this patch removes most of those places inside the IR generator. There are - still a few places we need to throw exceptions inside the IR generator, like - div/mod by 0. Those will be done in a separate patch. Also, there are - still some stubs we need to throw exceptions from; those will also be - done in a separate patch. - - All exceptions thrown from Wasm share a common stub. The ABI for the stub - is to move the Wasm::ExceptionType into argGPR1 and jump to the stub. - The stub will then throw an exception with an error message tailored - to the particular Wasm::ExceptionType failure. - - This patch also refactors B3::Compilation. Before, B3::Compilation(VM, Procedure) - constructor would compile a B3 function. This patch makes B3::Compilation a simple - tuple that keeps the necessary bits of B3 function alive in order to be runnable. - There is a new function that actually does the compilation for you. It is: - Compilation B3::compile(VM&, Procedure&) - The reason for this change is that I'm now using B3::Compilation(CodeRef, OpaqueByproducts) - constructor in Wasm code. It is weird to have a class both have a - constructor that instantiates the tuple, and another that performs the - compilation and then instantiates the tuple. It's more straight - forward if Compilation's job wasn't to actually do the compilation - but just to hold the necessary bits to keep a compiled B3 alive. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * b3/B3Compilation.cpp: - (JSC::B3::Compilation::Compilation): - * b3/B3Compilation.h: - * b3/B3Compile.cpp: Added. - (JSC::B3::compile): - * b3/B3Compile.h: Added. - * b3/testb3.cpp: - (JSC::B3::compile): - * jit/ThunkGenerators.cpp: - (JSC::throwExceptionFromWasmThunkGenerator): - * jit/ThunkGenerators.h: - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::B3IRGenerator::emitExceptionCheck): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmExceptionType.h: Added. - (JSC::Wasm::errorMessageForExceptionType): - -2016-12-16 Keith Miller - - i64.eqz should use an Int64 zero - https://bugs.webkit.org/show_bug.cgi?id=165942 - - Reviewed by Mark Lam. - - This patch fixes i64.eqz, which was using an Int32 zero - for the comparison previously. This patch also, adds - printing opcodes names in verbose mode. - - * wasm/WasmFunctionParser.h: - * wasm/generateWasmOpsHeader.py: - * wasm/wasm.json: - -2016-12-15 Darin Adler - - Use asString instead of toWTFString, toString, or getString when we already checked isString - https://bugs.webkit.org/show_bug.cgi?id=165895 - - Reviewed by Yusuke Suzuki. - - Once we have called isString, we should always use asString and value rather than using - functions that have to deal with non-JSString objects. This leads to slightly fewer branches, - slightly less reference count churn, since the string is stored right inside the JSString, - and obviates the need for exception handling. - - * bindings/ScriptValue.cpp: - (Inspector::jsToInspectorValue): Use asString/value instead of getString. - * dfg/DFGOperations.cpp: - (JSC::DFG::operationMapHash): Call jsMapHash with its new arguments. - * inspector/JSInjectedScriptHost.cpp: - (Inspector::JSInjectedScriptHost::evaluateWithScopeExtension): Use asString/value instead - of toWTFString. - * inspector/JSJavaScriptCallFrame.cpp: - (Inspector::JSJavaScriptCallFrame::evaluateWithScopeExtension): Ditto. - * inspector/agents/InspectorHeapAgent.cpp: - (Inspector::InspectorHeapAgent::getPreview): Use asString/tryGetValue, instead of the - peculiar getString(nullptr) that was here before. - * jsc.cpp: - (functionGetGetterSetter): Use asString/toIdentifier instead of the much less efficient - toWTFString/Identifier::fromString. - (functionIsRope): Use asString instead of jsCast; same thing, but we should - prefer the asString function, since it exists. - (functionFindTypeForExpression): Use asString/value instead of getString. - (functionHasBasicBlockExecuted): Ditto. - (functionBasicBlockExecutionCount): Ditto. - (functionCreateBuiltin): Use asString/value instead of toWTFString and removed - unneeded RETURN_IF_EXCEPTION. - (valueWithTypeOfWasmValue): Use asString instead of jsCast. - (box): Ditto. - * runtime/DateConstructor.cpp: - (JSC::constructDate): Use asString/values instead of getString. - * runtime/ExceptionHelpers.cpp: - (JSC::errorDescriptionForValue): Tweaked formatting. - - * runtime/HashMapImpl.h: - (JSC::jsMapHash): Changed this function to use asString/value. - - * runtime/JSCJSValue.cpp: - (JSC::JSValue::dumpInContextAssumingStructure): Use asString instead of - jsCast. - (JSC::JSValue::dumpForBacktrace): Ditto. - * runtime/JSCJSValueInlines.h: - (JSC::toPreferredPrimitiveType): Ditto. - - * runtime/JSGlobalObjectFunctions.cpp: - (JSC::globalFuncEval): Use asString/value instead of toWTFString. - - * runtime/JSString.cpp: - (JSC::JSString::destroy): Streamlined by removing local variable. - (JSC::JSString::estimatedSize): Use asString instead of jsCast. - (JSC::JSString::visitChildren): Ditto. - (JSC::JSString::toThis): Ditto. - * runtime/JSString.h: - (JSC::JSValue::toString): Ditto. - (JSC::JSValue::toStringOrNull): Ditto. - * runtime/NumberPrototype.cpp: - (JSC::numberProtoFuncValueOf): Ditto. - * runtime/ObjectPrototype.cpp: - (JSC::objectProtoFuncToString): Ditto. - * runtime/StringPrototype.cpp: - (JSC::stringProtoFuncRepeatCharacter): Ditto. - (JSC::stringProtoFuncSubstr): Ditto. - (JSC::builtinStringSubstrInternal): Simplified assertion by removing local variable. - -2016-12-15 Keith Miller - - Fix validation of non-void if blocks with no else - https://bugs.webkit.org/show_bug.cgi?id=165938 - - Reviewed by Saam Barati. - - We should not have been allowing non-void if-blocks that don't - have an else. Since this causes a value to be placed on the - stack that only appears under some control flow and not another. - - * wasm/WasmValidate.cpp: - -2016-12-15 Filip Pizlo - - Get rid of HeapRootVisitor and make SlotVisitor less painful to use - https://bugs.webkit.org/show_bug.cgi?id=165911 - - Reviewed by Geoffrey Garen. - - Previously we had two ways of adding a raw pointer to the GC's mark stack: - - - SlotVisitor::appendUnbarrieredXYZ() methods - - HeapRootVisitor::visit() methods - - HeapRootVisitor existed only to prevent you from calling its non-WriteBarrier<> methods - unless you had permission. But SlotVisitor would let you do it anyway, because that was - a lot more practical. - - I think that we should just have one way to do it. This removes HeapRootVisitor. It - also renames appendUnbarrieredXYZ to appendUnbarriered, and it removes the use of extra - indirection (so you now pass const WriteBarrier<>& instead of WriteBarrier<>*). - - * API/JSCallbackObject.h: - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): - * JavaScriptCore.xcodeproj/project.pbxproj: - * Scripts/builtins/builtins_templates.py: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::visitWeakly): - (JSC::CodeBlock::visitChildren): - (JSC::CodeBlock::propagateTransitions): - (JSC::CodeBlock::determineLiveness): - (JSC::CodeBlock::visitOSRExitTargets): - (JSC::CodeBlock::stronglyVisitStrongReferences): - (JSC::CodeBlock::stronglyVisitWeakReferences): - * bytecode/DirectEvalCodeCache.cpp: - (JSC::DirectEvalCodeCache::visitAggregate): - * bytecode/InternalFunctionAllocationProfile.h: - (JSC::InternalFunctionAllocationProfile::visitAggregate): - * bytecode/ObjectAllocationProfile.h: - (JSC::ObjectAllocationProfile::visitAggregate): - * bytecode/PolymorphicAccess.cpp: - (JSC::AccessCase::propagateTransitions): - * bytecode/UnlinkedCodeBlock.cpp: - (JSC::UnlinkedCodeBlock::visitChildren): - * bytecode/UnlinkedFunctionExecutable.cpp: - (JSC::UnlinkedFunctionExecutable::visitChildren): - * debugger/DebuggerScope.cpp: - (JSC::DebuggerScope::visitChildren): - * dfg/DFGDesiredTransitions.cpp: - (JSC::DFG::DesiredTransition::visitChildren): - * dfg/DFGDesiredWeakReferences.cpp: - (JSC::DFG::DesiredWeakReferences::visitChildren): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::visitChildren): - * dfg/DFGPlan.cpp: - (JSC::DFG::Plan::markCodeBlocks): - (JSC::DFG::Plan::checkLivenessAndVisitChildren): - * heap/HandleSet.cpp: - (JSC::HandleSet::visitStrongHandles): - * heap/HandleSet.h: - * heap/HandleStack.cpp: - (JSC::HandleStack::visit): - * heap/HandleStack.h: - * heap/Heap.cpp: - (JSC::Heap::markToFixpoint): - * heap/Heap.h: - * heap/HeapRootVisitor.h: Removed. - * heap/LargeAllocation.cpp: - (JSC::LargeAllocation::visitWeakSet): - * heap/LargeAllocation.h: - * heap/MarkedBlock.h: - (JSC::MarkedBlock::Handle::visitWeakSet): - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::visitWeakSets): - * heap/MarkedSpace.h: - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::appendUnbarriered): - * heap/SlotVisitor.h: - * heap/SlotVisitorInlines.h: - (JSC::SlotVisitor::appendUnbarriered): - (JSC::SlotVisitor::append): - (JSC::SlotVisitor::appendHidden): - (JSC::SlotVisitor::appendValues): - (JSC::SlotVisitor::appendValuesHidden): - (JSC::SlotVisitor::appendUnbarrieredPointer): Deleted. - (JSC::SlotVisitor::appendUnbarrieredReadOnlyPointer): Deleted. - (JSC::SlotVisitor::appendUnbarrieredValue): Deleted. - (JSC::SlotVisitor::appendUnbarrieredReadOnlyValue): Deleted. - (JSC::SlotVisitor::appendUnbarrieredWeak): Deleted. - * heap/WeakBlock.cpp: - (JSC::WeakBlock::specializedVisit): - (JSC::WeakBlock::visit): - * heap/WeakBlock.h: - * heap/WeakSet.h: - (JSC::WeakSet::visit): - * interpreter/ShadowChicken.cpp: - (JSC::ShadowChicken::visitChildren): - * jit/GCAwareJITStubRoutine.cpp: - (JSC::MarkingGCAwareJITStubRoutine::markRequiredObjectsInternal): - * jit/PolymorphicCallStubRoutine.cpp: - (JSC::PolymorphicCallStubRoutine::markRequiredObjectsInternal): - * jsc.cpp: - (WTF::Element::visitChildren): - (WTF::ImpureGetter::visitChildren): - (WTF::SimpleObject::visitChildren): - * runtime/AbstractModuleRecord.cpp: - (JSC::AbstractModuleRecord::visitChildren): - * runtime/ArgList.cpp: - (JSC::MarkedArgumentBuffer::markLists): - * runtime/ArgList.h: - * runtime/ClonedArguments.cpp: - (JSC::ClonedArguments::visitChildren): - * runtime/DirectArguments.cpp: - (JSC::DirectArguments::visitChildren): - * runtime/EvalExecutable.cpp: - (JSC::EvalExecutable::visitChildren): - * runtime/Exception.cpp: - (JSC::Exception::visitChildren): - * runtime/FunctionExecutable.cpp: - (JSC::FunctionExecutable::visitChildren): - * runtime/FunctionRareData.cpp: - (JSC::FunctionRareData::visitChildren): - * runtime/GetterSetter.cpp: - (JSC::GetterSetter::visitChildren): - * runtime/HashMapImpl.cpp: - (JSC::HashMapBucket::visitChildren): - (JSC::HashMapImpl::visitChildren): - * runtime/InferredTypeTable.cpp: - (JSC::InferredTypeTable::visitChildren): - * runtime/InternalFunction.cpp: - (JSC::InternalFunction::visitChildren): - * runtime/IntlCollator.cpp: - (JSC::IntlCollator::visitChildren): - * runtime/IntlCollatorConstructor.cpp: - (JSC::IntlCollatorConstructor::visitChildren): - * runtime/IntlDateTimeFormat.cpp: - (JSC::IntlDateTimeFormat::visitChildren): - * runtime/IntlDateTimeFormatConstructor.cpp: - (JSC::IntlDateTimeFormatConstructor::visitChildren): - * runtime/IntlNumberFormat.cpp: - (JSC::IntlNumberFormat::visitChildren): - * runtime/IntlNumberFormatConstructor.cpp: - (JSC::IntlNumberFormatConstructor::visitChildren): - * runtime/JSBoundFunction.cpp: - (JSC::JSBoundFunction::visitChildren): - * runtime/JSCallee.cpp: - (JSC::JSCallee::visitChildren): - * runtime/JSCellInlines.h: - (JSC::JSCell::visitChildren): - * runtime/JSCustomGetterSetterFunction.cpp: - (JSC::JSCustomGetterSetterFunction::visitChildren): - * runtime/JSFunction.cpp: - (JSC::JSFunction::visitChildren): - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::visitChildren): - * runtime/JSMapIterator.cpp: - (JSC::JSMapIterator::visitChildren): - * runtime/JSModuleEnvironment.cpp: - (JSC::JSModuleEnvironment::visitChildren): - * runtime/JSModuleNamespaceObject.cpp: - (JSC::JSModuleNamespaceObject::visitChildren): - * runtime/JSModuleRecord.cpp: - (JSC::JSModuleRecord::visitChildren): - * runtime/JSNativeStdFunction.cpp: - (JSC::JSNativeStdFunction::visitChildren): - * runtime/JSObject.cpp: - (JSC::JSObject::visitButterflyImpl): - * runtime/JSPromiseDeferred.cpp: - (JSC::JSPromiseDeferred::visitChildren): - * runtime/JSPropertyNameEnumerator.cpp: - (JSC::JSPropertyNameEnumerator::visitChildren): - * runtime/JSPropertyNameIterator.cpp: - (JSC::JSPropertyNameIterator::visitChildren): - * runtime/JSProxy.cpp: - (JSC::JSProxy::visitChildren): - * runtime/JSScope.cpp: - (JSC::JSScope::visitChildren): - * runtime/JSSegmentedVariableObject.cpp: - (JSC::JSSegmentedVariableObject::visitChildren): - * runtime/JSSetIterator.cpp: - (JSC::JSSetIterator::visitChildren): - * runtime/JSString.cpp: - (JSC::JSRopeString::visitFibers): - * runtime/JSSymbolTableObject.cpp: - (JSC::JSSymbolTableObject::visitChildren): - * runtime/JSWeakMap.cpp: - (JSC::JSWeakMap::visitChildren): - * runtime/JSWeakSet.cpp: - (JSC::JSWeakSet::visitChildren): - * runtime/JSWithScope.cpp: - (JSC::JSWithScope::visitChildren): - * runtime/JSWrapperObject.cpp: - (JSC::JSWrapperObject::visitChildren): - * runtime/LazyClassStructure.cpp: - (JSC::LazyClassStructure::visit): - * runtime/LazyPropertyInlines.h: - (JSC::ElementType>::visit): - * runtime/MapBase.cpp: - (JSC::MapBase::visitChildren): - * runtime/ModuleProgramExecutable.cpp: - (JSC::ModuleProgramExecutable::visitChildren): - * runtime/NativeErrorConstructor.cpp: - (JSC::NativeErrorConstructor::visitChildren): - * runtime/ProgramExecutable.cpp: - (JSC::ProgramExecutable::visitChildren): - * runtime/ProxyObject.cpp: - (JSC::ProxyObject::visitChildren): - * runtime/ProxyRevoke.cpp: - (JSC::ProxyRevoke::visitChildren): - * runtime/RegExpCachedResult.cpp: - (JSC::RegExpCachedResult::visitChildren): - * runtime/RegExpObject.cpp: - (JSC::RegExpObject::visitChildren): - * runtime/RegExpPrototype.cpp: - (JSC::RegExpPrototype::visitChildren): - * runtime/SamplingProfiler.cpp: - (JSC::SamplingProfiler::visit): - * runtime/ScopedArguments.cpp: - (JSC::ScopedArguments::visitChildren): - * runtime/SmallStrings.cpp: - (JSC::SmallStrings::visitStrongReferences): - * runtime/SparseArrayValueMap.cpp: - (JSC::SparseArrayValueMap::visitChildren): - * runtime/Structure.cpp: - (JSC::Structure::visitChildren): - (JSC::Structure::markIfCheap): - * runtime/StructureChain.cpp: - (JSC::StructureChain::visitChildren): - * runtime/StructureRareData.cpp: - (JSC::StructureRareData::visitChildren): - * runtime/SymbolTable.cpp: - (JSC::SymbolTable::visitChildren): - * runtime/TypeProfilerLog.cpp: - (JSC::TypeProfilerLog::visit): - * runtime/WeakMapData.cpp: - (JSC::WeakMapData::DeadKeyCleaner::visitWeakReferences): - * wasm/js/JSWebAssemblyInstance.cpp: - (JSC::JSWebAssemblyInstance::visitChildren): - * wasm/js/JSWebAssemblyMemory.cpp: - (JSC::JSWebAssemblyMemory::visitChildren): - * wasm/js/JSWebAssemblyModule.cpp: - (JSC::JSWebAssemblyModule::visitChildren): - * wasm/js/JSWebAssemblyTable.cpp: - (JSC::JSWebAssemblyTable::visitChildren): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::WebAssemblyFunction::visitChildren): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::visitChildren): - -2016-12-15 Myles C. Maxfield - - Sort Xcode project files - https://bugs.webkit.org/show_bug.cgi?id=165937 - - Reviewed by Simon Fraser. - - * JavaScriptCore.xcodeproj/project.pbxproj: - -2016-12-15 Keith Miller - - Wasm should not create empty unlinked callsites - https://bugs.webkit.org/show_bug.cgi?id=165933 - - Reviewed by Mark Lam. - - Wasm would create holes in the unlinked callsite vector if B3 was able to - eliminate the callsite. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::addCall): - -2016-12-15 JF Bastien - - WebAssembly: improve compilation error messages - https://bugs.webkit.org/show_bug.cgi?id=163919 - - Reviewed by Saam Barati. - - The error handling messages were underwhelming because most - locations merely returned `false` on failure. This patch uses - std::expected to denote that failure isn't expected. Doing this - makes it almost impossible to mess up the code: either a function - returns a result (or a partial result for internal helpers) or an - error. We're not synchronizing the error string with the m_failed - bool anymore, and the caller will abort if they try to get a - result but the outcome was an error. - - This also shortens the code significantly using macros, while also - judiciously preventing inlining of error handling code and biasing - towards success using UNLIKELY. This means that the generated code - should be more efficient (no string formatting on success, and - regalloc can avoid these unlikely paths). - - The patch adds a few missing checks as well, especially related to - count limits and memory allocation failure. - - As a follow-up I'd like to improve WTF::makeString further, so it - does coercions to string and understands ADL as I did in this - patch. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::fail): - (JSC::Wasm::parseAndCompile): - * wasm/WasmB3IRGenerator.h: - * wasm/WasmFormat.h: - (JSC::Wasm::isValidExternalKind): - (JSC::Wasm::makeString): - * wasm/WasmFunctionParser.h: - * wasm/WasmModuleParser.cpp: - * wasm/WasmModuleParser.h: - * wasm/WasmParser.h: - (JSC::Wasm::FailureHelper::makeString): - (JSC::Wasm::Parser::fail): - (JSC::Wasm::Parser::Parser): - (JSC::Wasm::Parser::consumeCharacter): - (JSC::Wasm::Parser::consumeString): - (JSC::Wasm::Parser::consumeUTF8String): - (JSC::Wasm::Parser::parseVarUInt32): - (JSC::Wasm::Parser::parseVarUInt64): - (JSC::Wasm::Parser::parseVarInt32): - (JSC::Wasm::Parser::parseVarInt64): - (JSC::Wasm::Parser::parseUInt32): - (JSC::Wasm::Parser::parseUInt64): - (JSC::Wasm::Parser::parseUInt8): - (JSC::Wasm::Parser::parseInt7): - (JSC::Wasm::Parser::parseUInt7): - (JSC::Wasm::Parser::parseVarUInt1): - (JSC::Wasm::Parser::parseResultType): - (JSC::Wasm::Parser::parseValueType): - (JSC::Wasm::Parser::parseExternalKind): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::run): - * wasm/WasmSections.h: - (JSC::Wasm::isValidSection): - (JSC::Wasm::validateOrder): - (JSC::Wasm::makeString): - * wasm/WasmValidate.cpp: - (JSC::Wasm::Validate::fail): - (JSC::Wasm::Validate::addUnreachable): - (JSC::Wasm::validateFunction): - * wasm/WasmValidate.h: - * wasm/generateWasmB3IRGeneratorInlinesHeader.py: - * wasm/generateWasmOpsHeader.py: - * wasm/generateWasmValidateInlinesHeader.py: - (loadMacro): - (storeMacro): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - -2016-12-15 JF Bastien - - WebAssembly API: improve data section errors, initialize after Element - https://bugs.webkit.org/show_bug.cgi?id=165733 - - Reviewed by Keith Miller. - - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseData): Data section without Memory section or import is a validation error - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::dataSegmentFail): - (JSC::WebAssemblyModuleRecord::evaluate): tighten checks (though the spec isn't fully baked), and move after Element initialization - -2016-12-15 Keith Miller - - Turn on WebAssembly by default - https://bugs.webkit.org/show_bug.cgi?id=165918 - - Reviewed by Saam Barati. - - * runtime/Options.h: - -2016-12-15 Konstantin Tokarev - - Added missing override and final specifiers - https://bugs.webkit.org/show_bug.cgi?id=165903 + -Wformat-truncation warning in ConfigFile.cpp + https://bugs.webkit.org/show_bug.cgi?id=174506 Reviewed by Darin Adler. - * bytecompiler/BytecodeGenerator.h: - * jsc.cpp: - * parser/Nodes.h: + Check if the JSC config filename would be truncated due to exceeding max path length. If so, + return ParseError. -2016-12-15 Chris Dumez + * runtime/ConfigFile.cpp: + (JSC::ConfigFile::parse): - Harden JSObject::getOwnPropertyDescriptor() - https://bugs.webkit.org/show_bug.cgi?id=165908 +2017-07-17 Konstantin Tokarev - Reviewed by Geoffrey Garen. - - * runtime/JSObject.cpp: - (JSC::JSObject::getOwnPropertyDescriptor): - -2016-12-15 Keith Miller - - Fix 64-bit shift family Wasm opcodes - https://bugs.webkit.org/show_bug.cgi?id=165902 - - Reviewed by Geoffrey Garen. - - The Int64 versions of the shift family B3 opcodes take an Int32 - for the shift value. Wasm, however, takes an i64, so we need to - Trunc the shift value. Also, this fixes a bug where shr_u mapped - to signed shift and shr_s mapped to the unsigned shift. - - * wasm/wasm.json: - -2016-12-14 Keith Miller - - Wasm should decode constants correctly - https://bugs.webkit.org/show_bug.cgi?id=165886 - - Reviewed by Saam Barati. - - This patch fixes how we decode the constant part of i32, i64, f32, - and f64.const opcodes. - - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/wasm.json: - -2016-12-14 Saam Barati - - WebAssembly: Add various low hanging fruit that will allow us to run the LLVM torture tests in Wasm - https://bugs.webkit.org/show_bug.cgi?id=165883 - - Reviewed by Keith Miller. - - This patch implements some low hanging fruit: - - Exporting Table - - Exporting Memory - - Load16 with zero extension to both 32 and 64 bit values. - - Fixes Unreachable to emit code that will prevent B3 from having a validation error. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::addUnreachable): - (JSC::Wasm::sizeOfLoadOp): - (JSC::Wasm::B3IRGenerator::emitLoadOp): - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseExport): - * wasm/WasmValidate.cpp: - (JSC::Wasm::Validate::addUnreachable): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::finishCreation): - (JSC::WebAssemblyModuleRecord::link): - -2016-12-14 Yusuke Suzuki - - Update ModuleLoader code by using the latest builtin primitives - https://bugs.webkit.org/show_bug.cgi?id=165851 - - Reviewed by Sam Weinig. - - Update the module loader code, - - 1. Use @globalPrivate for the utilities, instead of setting them as the member of ModuleLoader. - 2. Use @putByValDirect instead of @push. @push is user-observable since it uses Set() operation - and it can be observed by defining indexed setters in Array.prototype. - - * builtins/ModuleLoaderPrototype.js: - (ensureRegistered): - (fulfillFetch): - (commitInstantiated): - (requestFetch): - (requestSatisfy): - (setStateToMax): Deleted. - (newRegistryEntry): Deleted. - * runtime/ModuleLoaderPrototype.cpp: - -2016-12-14 Michael Saboff - - The stress GC bot crashes in JavaScriptCore beneath ShadowChicken::update and Inspector::jsToInspectorValue - https://bugs.webkit.org/show_bug.cgi?id=165871 - - Reviewed by Mark Lam. - - This fixes two issues with the VM watch dog timer firing in a worker. - - The first issue has to do with bytecode ordering. Prior to this change, the first few opcodes - generated when the watch dog is enabled are: - op_enter - op_watchdog - op_get_scope - When the watchdog fires, the function will get an exception at op_watchdog. In processing that exception, - we'll try to update the ShadowChicken shadow stack. That update assumes that if there is a scope - VirtualRegister allocated, then the slot contains a valid JSScope. With the current bytecode ordering, - this is not true at op_watchdog as op_enter will put JSUndefined in the scope slot. It isn't until the - op_get_scope gets processed that we'll have a valid scope in the slot. The fix for this issue is to - ensure that op_get_scope happens before the op_watchdog. - - The second issue is that ScriptFunctionCall::call() will not tell its caller that a terminated - execution exception happened. Instead call() returns an empty JSValue. InjectedScript::wrapCallFrames() - wasn't checking for an empty JSValue, but was passing it to another function. Added a short circuit - return when call returns an empty JSValue. - - Added to fix other callers of ScriptFunctionCall::call() - to check for an empty JSValue return value. - Also tracked with . - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::emitEnter): - * inspector/InjectedScript.cpp: - (Inspector::InjectedScript::wrapCallFrames): - -2016-12-14 Filip Pizlo - - DirectTailCall implementation needs to tell the shuffler what to put into the ArgumentCount explicitly - https://bugs.webkit.org/show_bug.cgi?id=165882 - - Reviewed by Mark Lam. - - The CallFrameShuffler was assuming that the ArgumentCount that it should store into the - callee frame is simply the size of the args vector. - - That's not true for DirectTailCall, which will pad the args vector with undefined if we - are optimizing an arity mismatch. We need to pass the ArgumentCount explicitly in this - case. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::compileDirectCallOrConstruct): - (JSC::FTL::DFG::LowerDFGToB3::compileTailCall): - * jit/CallFrameShuffleData.h: - * jit/CallFrameShuffler.cpp: - (JSC::CallFrameShuffler::CallFrameShuffler): - (JSC::CallFrameShuffler::prepareAny): - * jit/CallFrameShuffler.h: - (JSC::CallFrameShuffler::snapshot): - * jit/JITCall.cpp: - (JSC::JIT::compileOpCall): - -2016-12-14 Keith Miller - - WebAssembly JS API: implement Global - https://bugs.webkit.org/show_bug.cgi?id=164133 - - Reviewed by Saam Barati. - - This patch adds support for globals. It handles imports, exports - and internal globals. In the MVP only internal globals are allowed - to be mutable. This means we can store a C-array of 64-bit slots - off the instance holding them. When globals are exported to JS - they are done so as numbers. This means that i64 globals cannot be - imported or exported. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::B3IRGenerator::getGlobal): - (JSC::Wasm::B3IRGenerator::setGlobal): - (JSC::Wasm::B3IRGenerator::addCallIndirect): - (JSC::Wasm::parseAndCompile): - * wasm/WasmFormat.h: - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseImport): - (JSC::Wasm::ModuleParser::parseGlobal): - (JSC::Wasm::ModuleParser::parseExport): - (JSC::Wasm::ModuleParser::parseElement): - (JSC::Wasm::ModuleParser::parseInitExpr): - (JSC::Wasm::ModuleParser::parseGlobalType): - (JSC::Wasm::ModuleParser::parseData): - * wasm/WasmModuleParser.h: - * wasm/WasmParser.h: - (JSC::Wasm::Parser::parseVarInt32): - (JSC::Wasm::Parser::parseVarInt64): - (JSC::Wasm::Parser::parseUInt64): - * wasm/WasmValidate.cpp: - (JSC::Wasm::Validate::hasMemory): - (JSC::Wasm::Validate::Validate): - (JSC::Wasm::Validate::getGlobal): - (JSC::Wasm::Validate::setGlobal): - (JSC::Wasm::validateFunction): - * wasm/generateWasmOpsHeader.py: - * wasm/js/JSWebAssemblyInstance.cpp: - (JSC::JSWebAssemblyInstance::create): - (JSC::JSWebAssemblyInstance::finishCreation): - (JSC::JSWebAssemblyInstance::visitChildren): - * wasm/js/JSWebAssemblyInstance.h: - (JSC::JSWebAssemblyInstance::loadI32Global): - (JSC::JSWebAssemblyInstance::loadI64Global): - (JSC::JSWebAssemblyInstance::loadF32Global): - (JSC::JSWebAssemblyInstance::loadF64Global): - (JSC::JSWebAssemblyInstance::setGlobal): - (JSC::JSWebAssemblyInstance::offsetOfGlobals): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::finishCreation): - (JSC::WebAssemblyModuleRecord::link): - -2016-12-14 Filip Pizlo - - Unreviewed, re-enable concurrent GC on ARM64 now that the most likely culprit of the memory - regressions is fixed. Lets see what the bots think! - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - -2016-12-14 Filip Pizlo - - Devices with fewer cores should use a more aggressive GC schedule by default - https://bugs.webkit.org/show_bug.cgi?id=165859 - - Reviewed by Mark Lam. - - * heap/Heap.cpp: - (JSC::Heap::markToFixpoint): Log when we have an unexpected delay in wake-up. - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::drainInParallelPassively): Don't drain passively if there aren't many cores. - * runtime/Options.cpp: - (JSC::overrideDefaults): Change the heuristics if we have fewer cores. - (JSC::Options::initialize): - * runtime/Options.h: - -2016-12-14 Mark Lam - - BytecodeBasicBlock::computeImpl() should not keep iterating blocks if all jump targets have already been found. - https://bugs.webkit.org/show_bug.cgi?id=165820 - - Reviewed by Saam Barati. - - Currently, if an opcode is a branch type opcode, BytecodeBasicBlock::computeImpl() - will iterate over all basic blocks looking for the block containing the jump - target, and it will continue to do this even when all the jump targets have been - found. This is wasted work, and all the more so given that most branch type - opcodes only have a single jump target. - - * bytecode/BytecodeBasicBlock.cpp: - (JSC::BytecodeBasicBlock::computeImpl): - -2016-12-14 Gavin Barraclough - - MarkedBlock::marksConveyLivenessDuringMarking should take into account collection scope - https://bugs.webkit.org/show_bug.cgi?id=165741 - - Unreviewed, re-landing this with fix (revert erroneous change to Options). - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * heap/CellContainer.cpp: Added. - (JSC::CellContainer::isNewlyAllocated): - * heap/CellContainer.h: - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::addBlock): - (JSC::MarkedAllocator::removeBlock): - (JSC::MarkedAllocator::dumpBits): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::forEachBitVector): - (JSC::MarkedAllocator::forEachBitVectorWithName): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::tryCreate): - (JSC::MarkedBlock::Handle::~Handle): - (JSC::MarkedBlock::MarkedBlock): - (JSC::MarkedBlock::Handle::specializedSweep): - (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): - (JSC::MarkedBlock::Handle::stopAllocating): - (JSC::MarkedBlock::Handle::resumeAllocating): - (JSC::MarkedBlock::aboutToMarkSlow): - (JSC::MarkedBlock::Handle::didConsumeFreeList): - (JSC::MarkedBlock::Handle::dumpState): - * heap/MarkedBlock.h: - (JSC::MarkedBlock::markingVersion): - (JSC::MarkedBlock::isMarkedRaw): - (JSC::MarkedBlock::isMarked): - * heap/MarkedBlockInlines.h: - (JSC::MarkedBlock::marksConveyLivenessDuringMarking): - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::appendJSCellOrAuxiliary): - * runtime/StructureIDTable.h: - (JSC::StructureIDTable::size): - (JSC::StructureIDTable::get): - -2016-12-14 Chris Dumez - - Unreviewed, rolling out r209766. - - Regressed Dromaeo JSLib by ~50% - - Reverted changeset: - - "Make opaque root scanning truly constraint-based" - https://bugs.webkit.org/show_bug.cgi?id=165760 - http://trac.webkit.org/changeset/209766 - -2016-12-14 Commit Queue - - Unreviewed, rolling out r209795. - https://bugs.webkit.org/show_bug.cgi?id=165853 - - rolled out the wrong revision (Requested by pizlo on #webkit). - - Reverted changeset: - - "MarkedBlock::marksConveyLivenessDuringMarking should take - into account collection scope" - https://bugs.webkit.org/show_bug.cgi?id=165741 - http://trac.webkit.org/changeset/209795 - -2016-12-14 Filip Pizlo - - Unreviewed, disable concurrent GC on ARM while we investigate a memory use regression. - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - -2016-12-13 Yusuke Suzuki - - Use JSValue::toWTFString instead of calling toString(exec) and value(exec) - https://bugs.webkit.org/show_bug.cgi?id=165795 - - Reviewed by Saam Barati. - - In old days, we frequently use the idiom like, `value.toString(exec)->value(exec)` to - get WTFString from the given JSValue. But now, we have better function, `toWTFString`. - `toWTFString` does not create intermediate JSString objects, then reduce unnecessary - allocations. - - This patch mechanically replaces `value.toString(exec)->value(exec)` with `toWTFString(exec)`. - - * API/JSValueRef.cpp: - (JSValueToStringCopy): - * bindings/ScriptValue.cpp: - (Deprecated::ScriptValue::toString): - * inspector/JSGlobalObjectInspectorController.cpp: - (Inspector::JSGlobalObjectInspectorController::reportAPIException): - * inspector/JSInjectedScriptHost.cpp: - (Inspector::JSInjectedScriptHost::evaluateWithScopeExtension): - * inspector/JSJavaScriptCallFrame.cpp: - (Inspector::JSJavaScriptCallFrame::evaluateWithScopeExtension): - * inspector/ScriptCallStackFactory.cpp: - (Inspector::extractSourceInformationFromException): - * runtime/ConsoleObject.cpp: - (JSC::valueToStringWithUndefinedOrNullCheck): - (JSC::valueOrDefaultLabelString): - * runtime/DateConstructor.cpp: - (JSC::dateParse): - * runtime/DatePrototype.cpp: - (JSC::formatLocaleDate): - * runtime/ErrorInstance.cpp: - (JSC::ErrorInstance::sanitizedToString): - * runtime/ErrorPrototype.cpp: - (JSC::errorProtoFuncToString): - * runtime/InspectorInstrumentationObject.cpp: - (JSC::inspectorInstrumentationObjectLog): - * runtime/JSGlobalObjectFunctions.cpp: - (JSC::globalFuncEval): - * runtime/JSModuleLoader.cpp: - (JSC::JSModuleLoader::fetch): - * runtime/ModuleLoaderPrototype.cpp: - (JSC::moduleLoaderPrototypeParseModule): - * runtime/RegExpConstructor.cpp: - (JSC::regExpCreate): - * runtime/RegExpPrototype.cpp: - (JSC::regExpProtoFuncCompile): - (JSC::regExpProtoFuncToString): - * runtime/StringPrototype.cpp: - (JSC::replaceUsingRegExpSearch): - (JSC::replaceUsingStringSearch): - (JSC::stringProtoFuncSlice): - (JSC::stringProtoFuncSplitFast): - (JSC::stringProtoFuncSubstr): - (JSC::stringProtoFuncLocaleCompare): - (JSC::stringProtoFuncBig): - (JSC::stringProtoFuncSmall): - (JSC::stringProtoFuncBlink): - (JSC::stringProtoFuncBold): - (JSC::stringProtoFuncFixed): - (JSC::stringProtoFuncItalics): - (JSC::stringProtoFuncStrike): - (JSC::stringProtoFuncSub): - (JSC::stringProtoFuncSup): - (JSC::stringProtoFuncFontcolor): - (JSC::stringProtoFuncFontsize): - (JSC::stringProtoFuncAnchor): - (JSC::stringProtoFuncLink): - (JSC::trimString): - (JSC::stringProtoFuncStartsWith): - (JSC::stringProtoFuncEndsWith): - (JSC::stringProtoFuncIncludes): - (JSC::builtinStringIncludesInternal): - (JSC::stringProtoFuncNormalize): - * tools/JSDollarVMPrototype.cpp: - (JSC::functionPrint): - * wasm/js/JSWebAssemblyCompileError.h: - (JSC::JSWebAssemblyCompileError::create): - * wasm/js/JSWebAssemblyRuntimeError.h: - (JSC::JSWebAssemblyRuntimeError::create): - -2016-12-14 Gavin Barraclough - - MarkedBlock::marksConveyLivenessDuringMarking should take into account collection scope - https://bugs.webkit.org/show_bug.cgi?id=165741 - - Unreviewed rollout due to performance regression. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * heap/CellContainer.cpp: Removed. - * heap/CellContainer.h: - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::addBlock): - (JSC::MarkedAllocator::removeBlock): - (JSC::MarkedAllocator::dumpBits): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::forEachBitVector): - (JSC::MarkedAllocator::forEachBitVectorWithName): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::tryCreate): - (JSC::MarkedBlock::Handle::~Handle): - (JSC::MarkedBlock::MarkedBlock): - (JSC::MarkedBlock::Handle::specializedSweep): - (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): - (JSC::MarkedBlock::Handle::stopAllocating): - (JSC::MarkedBlock::Handle::resumeAllocating): - (JSC::MarkedBlock::aboutToMarkSlow): - (JSC::MarkedBlock::Handle::didConsumeFreeList): - (JSC::MarkedBlock::Handle::dumpState): Deleted. - * heap/MarkedBlock.h: - (JSC::MarkedBlock::isMarked): - (JSC::MarkedBlock::markingVersion): Deleted. - (JSC::MarkedBlock::isMarkedRaw): Deleted. - * heap/MarkedBlockInlines.h: - (JSC::MarkedBlock::marksConveyLivenessDuringMarking): - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::appendJSCellOrAuxiliary): - * runtime/Options.h: - * runtime/StructureIDTable.h: - (JSC::StructureIDTable::get): - (JSC::StructureIDTable::size): Deleted. - -2016-12-13 Commit Queue - - Unreviewed, rolling out r209792. - https://bugs.webkit.org/show_bug.cgi?id=165841 - - Cause build failures (Requested by yusukesuzuki on #webkit). - - Reverted changeset: - - "Use JSValue::toWTFString instead of calling toString(exec) - and value(exec)" - https://bugs.webkit.org/show_bug.cgi?id=165795 - http://trac.webkit.org/changeset/209792 - -2016-12-13 Yusuke Suzuki - - Use JSValue::toWTFString instead of calling toString(exec) and value(exec) - https://bugs.webkit.org/show_bug.cgi?id=165795 - - Reviewed by Saam Barati. - - In old days, we frequently use the idiom like, `value.toString(exec)->value(exec)` to - get WTFString from the given JSValue. But now, we have better function, `toWTFString`. - `toWTFString` does not create intermediate JSString objects, then reduce unnecessary - allocations. - - This patch mechanically replaces `value.toString(exec)->value(exec)` with `toWTFString(exec)`. - - * API/JSValueRef.cpp: - (JSValueToStringCopy): - * bindings/ScriptValue.cpp: - (Deprecated::ScriptValue::toString): - * inspector/JSGlobalObjectInspectorController.cpp: - (Inspector::JSGlobalObjectInspectorController::reportAPIException): - * inspector/JSInjectedScriptHost.cpp: - (Inspector::JSInjectedScriptHost::evaluateWithScopeExtension): - * inspector/JSJavaScriptCallFrame.cpp: - (Inspector::JSJavaScriptCallFrame::evaluateWithScopeExtension): - * inspector/ScriptCallStackFactory.cpp: - (Inspector::extractSourceInformationFromException): - * runtime/ConsoleObject.cpp: - (JSC::valueToStringWithUndefinedOrNullCheck): - (JSC::valueOrDefaultLabelString): - * runtime/DateConstructor.cpp: - (JSC::dateParse): - * runtime/DatePrototype.cpp: - (JSC::formatLocaleDate): - * runtime/ErrorInstance.cpp: - (JSC::ErrorInstance::sanitizedToString): - * runtime/ErrorPrototype.cpp: - (JSC::errorProtoFuncToString): - * runtime/InspectorInstrumentationObject.cpp: - (JSC::inspectorInstrumentationObjectLog): - * runtime/JSCJSValue.cpp: - (JSC::JSValue::toWTFStringSlowCase): - * runtime/JSGlobalObjectFunctions.cpp: - (JSC::globalFuncEval): - * runtime/JSModuleLoader.cpp: - (JSC::JSModuleLoader::fetch): - * runtime/ModuleLoaderPrototype.cpp: - (JSC::moduleLoaderPrototypeParseModule): - * runtime/RegExpConstructor.cpp: - (JSC::regExpCreate): - * runtime/RegExpPrototype.cpp: - (JSC::regExpProtoFuncCompile): - (JSC::regExpProtoFuncToString): - * runtime/StringPrototype.cpp: - (JSC::replaceUsingRegExpSearch): - (JSC::replaceUsingStringSearch): - (JSC::stringProtoFuncSlice): - (JSC::stringProtoFuncSplitFast): - (JSC::stringProtoFuncSubstr): - (JSC::stringProtoFuncLocaleCompare): - (JSC::stringProtoFuncBig): - (JSC::stringProtoFuncSmall): - (JSC::stringProtoFuncBlink): - (JSC::stringProtoFuncBold): - (JSC::stringProtoFuncFixed): - (JSC::stringProtoFuncItalics): - (JSC::stringProtoFuncStrike): - (JSC::stringProtoFuncSub): - (JSC::stringProtoFuncSup): - (JSC::stringProtoFuncFontcolor): - (JSC::stringProtoFuncFontsize): - (JSC::stringProtoFuncAnchor): - (JSC::stringProtoFuncLink): - (JSC::trimString): - (JSC::stringProtoFuncStartsWith): - (JSC::stringProtoFuncEndsWith): - (JSC::stringProtoFuncIncludes): - (JSC::builtinStringIncludesInternal): - (JSC::stringProtoFuncNormalize): - * tools/JSDollarVMPrototype.cpp: - (JSC::functionPrint): - * wasm/js/JSWebAssemblyCompileError.h: - (JSC::JSWebAssemblyCompileError::create): - * wasm/js/JSWebAssemblyRuntimeError.h: - (JSC::JSWebAssemblyRuntimeError::create): - -2016-12-13 Saam Barati - - WebAssembly: implement the elements section - https://bugs.webkit.org/show_bug.cgi?id=165715 - - Reviewed by Keith Miller. - - This is a straight forward implementation of the Element - section in the Wasm spec: - https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#element-section - - There are a few ambiguities I encountered when implementing this, so I've - filed bugs against the Wasm design repo, and corresponding bugzilla bugs - for us to address after they've been discussed by the various Wasm folks: - - https://bugs.webkit.org/show_bug.cgi?id=165827 - - https://bugs.webkit.org/show_bug.cgi?id=165826 - - https://bugs.webkit.org/show_bug.cgi?id=165825 - - * wasm/WasmFormat.h: - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseElement): - (JSC::Wasm::ModuleParser::parseInitExpr): - (JSC::Wasm::ModuleParser::parseData): - * wasm/WasmModuleParser.h: - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::evaluate): - -2016-12-13 Chris Dumez - - Unreviewed, rolling out r209544. - - Looks like r209489 did not cause the performance regression - after all - - Reverted changeset: - - "Unreviewed, rolling out r209489." - https://bugs.webkit.org/show_bug.cgi?id=165550 - http://trac.webkit.org/changeset/209544 - -2016-12-13 Saam Barati - - WebAssembly: implement the table section and table import - https://bugs.webkit.org/show_bug.cgi?id=165716 - - Reviewed by Keith Miller. - - This patch implements the Table space for wasm: - https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#table-section - - It only implements defining and importing a table. The bulk - of this patch is implementing the various wasm Table prototype - methods and the underlying Table object: - https://github.com/WebAssembly/design/blob/master/JS.md#webassemblytable-constructor - - This patch also fixes a bug in our implementation with call_indirect. - We initially implemented call_indirect as a way to call functions that - are imported or defined in the module. This was the wrong - interpretation of the spec. Instead, call_indirect can only index into - the table index space. - - * JavaScriptCore.xcodeproj/project.pbxproj: - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::B3IRGenerator::addCallIndirect): - (JSC::Wasm::parseAndCompile): - * wasm/WasmFormat.h: - (JSC::Wasm::TableInformation::TableInformation): - (JSC::Wasm::TableInformation::operator bool): - (JSC::Wasm::TableInformation::isImport): - (JSC::Wasm::TableInformation::initial): - (JSC::Wasm::TableInformation::maximum): - (JSC::Wasm::CallableFunction::CallableFunction): - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseImport): - (JSC::Wasm::ModuleParser::parseResizableLimits): - (JSC::Wasm::ModuleParser::parseTableHelper): - (JSC::Wasm::ModuleParser::parseTable): - (JSC::Wasm::ModuleParser::parseMemoryHelper): - (JSC::Wasm::ModuleParser::parseExport): - * wasm/WasmModuleParser.h: - * wasm/js/JSWebAssemblyHelpers.h: Added. - (JSC::toNonWrappingUint32): - * wasm/js/JSWebAssemblyInstance.cpp: - (JSC::JSWebAssemblyInstance::visitChildren): - * wasm/js/JSWebAssemblyInstance.h: - (JSC::JSWebAssemblyInstance::table): - (JSC::JSWebAssemblyInstance::setTable): - (JSC::JSWebAssemblyInstance::offsetOfTable): - * wasm/js/JSWebAssemblyTable.cpp: - (JSC::JSWebAssemblyTable::create): - (JSC::JSWebAssemblyTable::JSWebAssemblyTable): - (JSC::JSWebAssemblyTable::visitChildren): - (JSC::JSWebAssemblyTable::grow): - (JSC::JSWebAssemblyTable::clearFunction): - (JSC::JSWebAssemblyTable::setFunction): - * wasm/js/JSWebAssemblyTable.h: - (JSC::JSWebAssemblyTable::maximum): - (JSC::JSWebAssemblyTable::size): - (JSC::JSWebAssemblyTable::getFunction): - (JSC::JSWebAssemblyTable::offsetOfSize): - (JSC::JSWebAssemblyTable::offsetOfFunctions): - (JSC::JSWebAssemblyTable::isValidSize): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::WebAssemblyFunction::call): - (JSC::WebAssemblyFunction::create): - (JSC::WebAssemblyFunction::visitChildren): - (JSC::WebAssemblyFunction::finishCreation): - * wasm/js/WebAssemblyFunction.h: - (JSC::WebAssemblyFunction::signature): - (JSC::WebAssemblyFunction::wasmEntrypoint): - (JSC::WebAssemblyFunction::webAssemblyCallee): Deleted. - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyMemoryConstructor.cpp: - (JSC::constructJSWebAssemblyMemory): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::finishCreation): - (JSC::WebAssemblyModuleRecord::link): - * wasm/js/WebAssemblyTableConstructor.cpp: - (JSC::constructJSWebAssemblyTable): - * wasm/js/WebAssemblyTablePrototype.cpp: - (JSC::getTable): - (JSC::webAssemblyTableProtoFuncLength): - (JSC::webAssemblyTableProtoFuncGrow): - (JSC::webAssemblyTableProtoFuncGet): - (JSC::webAssemblyTableProtoFuncSet): - (JSC::WebAssemblyTablePrototype::create): - (JSC::WebAssemblyTablePrototype::finishCreation): - * wasm/js/WebAssemblyTablePrototype.h: - -2016-12-13 Filip Pizlo - - Add null checks to opaque root APIs. - - Rubber stamped by Saam Barati. - - If we got a crash report about null in the opaque root HashSet, we would probably not - celebrate how great it is that we found out about a new race - instead we would probably - be annoyed that null wasn't just silently ignored. - - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::addOpaqueRoot): - (JSC::SlotVisitor::containsOpaqueRoot): - (JSC::SlotVisitor::containsOpaqueRootTriState): - -2016-12-13 Filip Pizlo - - Make opaque root scanning truly constraint-based - https://bugs.webkit.org/show_bug.cgi?id=165760 - - Reviewed by Saam Barati. - - We have bugs when visitChildren() changes its mind about what opaque root to add, since - we don't have barriers on opaque roots. This supposedly once worked for generational GC, - and I started adding more barriers to support concurrent GC. But I think that the real - bug here is that we want the JSObject->OpaqueRoot to be evaluated as a constraint that - participates in the fixpoint. A constraint is different from the normal visiting in that - the GC will not wait for a barrier to rescan the object. - - So, it's now possible for any visitChildren() method to become a constraint by calling - slotVisitor.rescanAsConstraint(). Because opaque roots are constraints, addOpaqueRoot() - does rescanAsConstraint() for you. - - The constraint set is simply a HashSet that accumulates with every - rescanAsConstraint() call and is only cleared at the start of full GC. This trivially - resolves most classes of GC bugs that would have arisen from opaque roots being changed - in a way that the GC did not anticipate. - - Looks like this is perf-neutral. - - * heap/Heap.cpp: - (JSC::Heap::markToFixpoint): - (JSC::Heap::setMutatorShouldBeFenced): - (JSC::Heap::writeBarrierOpaqueRootSlow): Deleted. - (JSC::Heap::addMutatorShouldBeFencedCache): Deleted. - * heap/Heap.h: - * heap/HeapInlines.h: - (JSC::Heap::writeBarrierOpaqueRoot): Deleted. - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::visitWeakSets): - * heap/MarkedSpace.h: - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::visitChildren): - (JSC::SlotVisitor::visitSubsequently): - (JSC::SlotVisitor::drain): - (JSC::SlotVisitor::addOpaqueRoot): - (JSC::SlotVisitor::rescanAsConstraint): - (JSC::SlotVisitor::mergeIfNecessary): - (JSC::SlotVisitor::mergeOpaqueRootsAndConstraints): - (JSC::SlotVisitor::mergeOpaqueRootsIfNecessary): Deleted. - * heap/SlotVisitor.h: - * heap/SlotVisitorInlines.h: - (JSC::SlotVisitor::reportExtraMemoryVisited): - (JSC::SlotVisitor::reportExternalMemoryVisited): - (JSC::SlotVisitor::didNotRace): - * heap/WeakBlock.cpp: - (JSC::WeakBlock::specializedVisit): - (JSC::WeakBlock::visit): - * heap/WeakBlock.h: - * heap/WeakSet.h: - (JSC::WeakSet::visit): - -2016-12-13 Commit Queue - - Unreviewed, rolling out r209725. - https://bugs.webkit.org/show_bug.cgi?id=165811 - - "Broke ARMv7 builds" (Requested by msaboff on #webkit). - - Reverted changeset: - - "REGRESSION(r209653): speedometer crashes making virtual slow - path tailcalls" - https://bugs.webkit.org/show_bug.cgi?id=165748 - http://trac.webkit.org/changeset/209725 - -2016-12-13 Filip Pizlo - - Unreviewed, revert the collectorPermittedIdleRatio back to 0 because of 100MB - regression on membuster. Also, it didn't seem to help perf. - - * runtime/Options.h: - -2016-12-13 JF Bastien - - [WTF] Turn tryMakeString(), makeString() into variadic templates - https://bugs.webkit.org/show_bug.cgi?id=147142 - - Reviewed by Mark Lam. - - * runtime/JSStringBuilder.h: - (JSC::jsMakeNontrivialString): remove WTF:: prefix, it isn't needed anymore - * runtime/Lookup.cpp: - (JSC::reifyStaticAccessor): remove WTF:: prefix, it isn't needed anymore - * runtime/ObjectPrototype.cpp: - (JSC::objectProtoFuncToString): remove WTF:: prefix, it isn't needed anymore - -2016-12-12 Mark Lam - - Rename BytecodeGenerator's ControlFlowContext to ControlFlowScope. - https://bugs.webkit.org/show_bug.cgi?id=165777 - - Reviewed by Keith Miller. - - The existing code sometimes refer to ControlFlowContext (and associated references) - as context, and sometimes as scope. Let's be consistent and always call it a scope. - - Also renamed push/popScopedControlFlowContext() to push/popLocalControlFlowScope() - because these are only used when we inc/dec the m_localScopeDepth. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::initializeVarLexicalEnvironment): - (JSC::BytecodeGenerator::pushLexicalScopeInternal): - (JSC::BytecodeGenerator::popLexicalScopeInternal): - (JSC::BytecodeGenerator::emitPushWithScope): - (JSC::BytecodeGenerator::emitPopWithScope): - (JSC::BytecodeGenerator::pushFinallyControlFlowScope): - (JSC::BytecodeGenerator::pushIteratorCloseControlFlowScope): - (JSC::BytecodeGenerator::popFinallyControlFlowScope): - (JSC::BytecodeGenerator::popIteratorCloseControlFlowScope): - (JSC::BytecodeGenerator::emitComplexPopScopes): - (JSC::BytecodeGenerator::emitPopScopes): - (JSC::BytecodeGenerator::pushLocalControlFlowScope): - (JSC::BytecodeGenerator::popLocalControlFlowScope): - (JSC::BytecodeGenerator::emitEnumeration): - (JSC::BytecodeGenerator::pushFinallyContext): Deleted. - (JSC::BytecodeGenerator::pushIteratorCloseContext): Deleted. - (JSC::BytecodeGenerator::popFinallyContext): Deleted. - (JSC::BytecodeGenerator::popIteratorCloseContext): Deleted. - (JSC::BytecodeGenerator::pushScopedControlFlowContext): Deleted. - (JSC::BytecodeGenerator::popScopedControlFlowContext): Deleted. - * bytecompiler/BytecodeGenerator.h: - * bytecompiler/NodesCodegen.cpp: - (JSC::TryNode::emitBytecode): - -2016-12-12 Filip Pizlo - - GC scheduler should avoid consecutive pauses - https://bugs.webkit.org/show_bug.cgi?id=165758 - - Reviewed by Michael Saboff. - - This factors out the scheduler from lambdas in Heap::markToFixpoint to an actual class. - It's called the SpaceTimeScheduler because it is a linear controller that ties the - amount of time you spend on things to the amount of space you are using. - - This patch uses this refactoring to fix a bug where the GC would pause even though we - still had time during a mutator timeslice. This is a 15% improvement on - JetStream/splay-latency. Seems neutral on everything else. However, it's not at all - clear if this is the right policy or not since retreating wavefront can sometimes be so - sensitive to scheduling decisions. For this reason, there is a tunable option that lets - you decide how long the GC will sit idle before the start of its timeslice. - - So, we can revert this policy change in this patch without reverting the patch. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * heap/Heap.cpp: - (JSC::Heap::markToFixpoint): - * heap/Heap.h: - * heap/SpaceTimeScheduler.cpp: Added. - (JSC::SpaceTimeScheduler::Decision::targetMutatorUtilization): - (JSC::SpaceTimeScheduler::Decision::targetCollectorUtilization): - (JSC::SpaceTimeScheduler::Decision::elapsedInPeriod): - (JSC::SpaceTimeScheduler::Decision::phase): - (JSC::SpaceTimeScheduler::Decision::shouldBeResumed): - (JSC::SpaceTimeScheduler::Decision::timeToResume): - (JSC::SpaceTimeScheduler::Decision::timeToStop): - (JSC::SpaceTimeScheduler::SpaceTimeScheduler): - (JSC::SpaceTimeScheduler::snapPhase): - (JSC::SpaceTimeScheduler::currentDecision): - * heap/SpaceTimeScheduler.h: Added. - (JSC::SpaceTimeScheduler::Decision::Decision): - (JSC::SpaceTimeScheduler::Decision::operator bool): - * runtime/Options.h: - -2016-12-12 Michael Saboff - - REGRESSION(r209653): speedometer crashes making virtual slow path tailcalls - https://bugs.webkit.org/show_bug.cgi?id=165748 - - Reviewed by Filip Pizlo. - - The virtual slow path for tailcalls always passes arguments on the stack. - The fix here is to link to the stack argument entrypoint instead of a register - argument entrypoint. - - While fixing this bug, I found that we weren't clearing the code origin when - shuffling the call frame for a register argument tailcall. - - Also rolling back in r209653, r209654, r209663, and r209673. - - * jit/CallFrameShuffler.cpp: - (JSC::CallFrameShuffler::prepareAny): - * jit/ThunkGenerators.cpp: - (JSC::virtualThunkFor): - -2016-12-12 Mark Lam - - Rename BytecodeGenerator's m_symbolTableStack to m_lexicalScopeStack. - https://bugs.webkit.org/show_bug.cgi?id=165768 - - Reviewed by Saam Barati. - - The lexical scope in "m_lexicalScopeStack" here refers to a pair of { } in the - source code that bounds the scope of variables. - - There are 4 places in the code where we call m_symbolTableStack.append() to - append a new stack entry. In only 3 of the 4 cases, a symbol table is provided - in the new stack entry. In all 4 cases, a scope register is provided in the new - stack entry. - - Also, 3 of the 4 functions that appends an entry to this stack are named: - 1. initializeVarLexicalEnvironment() - 2. pushLexicalScopeInternal() - 3. emitPushWithScope() - - The 4th function is the BytecodeGenerator constructor where it pushes the scope - for a module environment. - - Based on these details, m_lexicalScopeStack is a better name for this stack than - m_symbolTableStack. - - * bytecompiler/BytecodeGenerator.cpp: - (JSC::BytecodeGenerator::BytecodeGenerator): - (JSC::BytecodeGenerator::initializeArrowFunctionContextScopeIfNeeded): - (JSC::BytecodeGenerator::initializeVarLexicalEnvironment): - (JSC::BytecodeGenerator::pushLexicalScopeInternal): - (JSC::BytecodeGenerator::initializeBlockScopedFunctions): - (JSC::BytecodeGenerator::hoistSloppyModeFunctionIfNecessary): - (JSC::BytecodeGenerator::popLexicalScopeInternal): - (JSC::BytecodeGenerator::prepareLexicalScopeForNextForLoopIteration): - (JSC::BytecodeGenerator::variable): - (JSC::BytecodeGenerator::resolveType): - (JSC::BytecodeGenerator::emitResolveScope): - (JSC::BytecodeGenerator::emitPushWithScope): - (JSC::BytecodeGenerator::emitPopWithScope): - (JSC::BytecodeGenerator::pushFinallyContext): - (JSC::BytecodeGenerator::pushIteratorCloseContext): - (JSC::BytecodeGenerator::emitComplexPopScopes): - (JSC::BytecodeGenerator::popTryAndEmitCatch): - (JSC::BytecodeGenerator::emitPushFunctionNameScope): - * bytecompiler/BytecodeGenerator.h: - -2016-12-12 Saam Barati - - Unreviewed. Try to fix the cloop build. - - * interpreter/StackVisitor.cpp: - (JSC::StackVisitor::Frame::calleeSaveRegisters): - * interpreter/StackVisitor.h: - -2016-12-12 Michael Saboff - - FTL: Dumping disassembly requires that code origin is set when making polymorphic tail calls. - https://bugs.webkit.org/show_bug.cgi?id=165747 - - Reviewed by Filip Pizlo. - - Setting the code origin needs to be done for both the fast and slow path as we might need - it when linking a polymorphic or virtual call stub. - - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::compileTailCall): - -2016-12-11 Saam Barati - - Unreviewed. Try to fix the linux build. - - * runtime/StackFrame.h: - -2016-12-11 Saam Barati - - We should be able to throw exceptions from Wasm code and when Wasm frames are on the stack - https://bugs.webkit.org/show_bug.cgi?id=165429 - - Reviewed by Keith Miller. - - This patch teaches the stack walking runtime about wasm. - To do this, I taught StackVisitor that a callee is not - always an object. - - To be able to unwind callee save registers properly, I've given - JSWebAssemblyCallee a list of RegisterAtOffsetList for the callee - saves that B3 saved in the prologue. Also, because we have two - B3Compilations per wasm function, one for wasm entrypoint, and - one for the JS entrypoint, I needed to create a callee for each - because they each might spill callee save registers. - - I also fixed a bug inside the Wasm::Memory constructor where we - were trying to mmap the same number of bytes even after the first - mmap failed. We should start by trying to mmap the maximum bytes, - and if that fails, fall back to the specified initial bytes. However, - the code was just mmapping the maximum twice. I've fixed that and - also added a RELEASE_ASSERT_NOT_REACHED() for when the second mmap - fails along with a FIXME to throw an OOM error. - - There was a second bug I fixed where JSModuleRecord was calling - visitWeak on its CallLinkInfos inside ::visitChldren(). It needs - to do this after marking. I changed JSModuleRecord to do what - CodeBlock does and call visitWeak on its CallLinkInfos inside - an UnconditionalFinalizer. - - * API/JSContextRef.cpp: - (BacktraceFunctor::operator()): - * inspector/ScriptCallStackFactory.cpp: - (Inspector::createScriptCallStackFromException): - * interpreter/CallFrame.cpp: - (JSC::CallFrame::vmEntryGlobalObject): - * interpreter/CallFrame.h: - (JSC::ExecState::callee): - * interpreter/Interpreter.cpp: - (JSC::GetStackTraceFunctor::operator()): - (JSC::UnwindFunctor::operator()): - (JSC::UnwindFunctor::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer): - * interpreter/Interpreter.h: - * interpreter/ShadowChicken.cpp: - (JSC::ShadowChicken::update): - * interpreter/StackVisitor.cpp: - (JSC::StackVisitor::StackVisitor): - (JSC::StackVisitor::readFrame): - (JSC::StackVisitor::readNonInlinedFrame): - (JSC::StackVisitor::readInlinedFrame): - (JSC::StackVisitor::Frame::isWasmFrame): - (JSC::StackVisitor::Frame::codeType): - (JSC::StackVisitor::Frame::calleeSaveRegisters): - (JSC::StackVisitor::Frame::functionName): - (JSC::StackVisitor::Frame::sourceURL): - (JSC::StackVisitor::Frame::toString): - (JSC::StackVisitor::Frame::hasLineAndColumnInfo): - (JSC::StackVisitor::Frame::setToEnd): - * interpreter/StackVisitor.h: - (JSC::StackVisitor::Frame::callee): - (JSC::StackVisitor::Frame::isNativeFrame): - (JSC::StackVisitor::Frame::isJSFrame): Deleted. - * jsc.cpp: - (callWasmFunction): - (functionTestWasmModuleFunctions): - * runtime/Error.cpp: - (JSC::addErrorInfoAndGetBytecodeOffset): - * runtime/JSCell.cpp: - (JSC::JSCell::isAnyWasmCallee): - * runtime/JSCell.h: - * runtime/JSFunction.cpp: - (JSC::RetrieveArgumentsFunctor::operator()): - (JSC::RetrieveCallerFunctionFunctor::operator()): - * runtime/StackFrame.cpp: - (JSC::StackFrame::sourceID): - (JSC::StackFrame::sourceURL): - (JSC::StackFrame::functionName): - (JSC::StackFrame::computeLineAndColumn): - (JSC::StackFrame::toString): - * runtime/StackFrame.h: - (JSC::StackFrame::StackFrame): - (JSC::StackFrame::hasLineAndColumnInfo): - (JSC::StackFrame::hasBytecodeOffset): - (JSC::StackFrame::bytecodeOffset): - (JSC::StackFrame::isNative): Deleted. - * runtime/VM.h: - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmCallingConvention.h: - (JSC::Wasm::CallingConvention::setupFrameInPrologue): - * wasm/WasmFormat.h: - * wasm/WasmMemory.cpp: - (JSC::Wasm::Memory::Memory): - * wasm/WasmMemory.h: - (JSC::Wasm::Memory::isValid): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::run): - (JSC::Wasm::Plan::initializeCallees): - * wasm/WasmPlan.h: - (JSC::Wasm::Plan::jsToWasmEntryPointForFunction): Deleted. - * wasm/js/JSWebAssemblyCallee.cpp: - (JSC::JSWebAssemblyCallee::finishCreation): - * wasm/js/JSWebAssemblyCallee.h: - (JSC::JSWebAssemblyCallee::create): - (JSC::JSWebAssemblyCallee::entrypoint): - (JSC::JSWebAssemblyCallee::calleeSaveRegisters): - (JSC::JSWebAssemblyCallee::jsToWasmEntryPoint): Deleted. - * wasm/js/JSWebAssemblyModule.cpp: - (JSC::JSWebAssemblyModule::JSWebAssemblyModule): - (JSC::JSWebAssemblyModule::visitChildren): - (JSC::JSWebAssemblyModule::UnconditionalFinalizer::finalizeUnconditionally): - * wasm/js/JSWebAssemblyModule.h: - (JSC::JSWebAssemblyModule::jsEntrypointCalleeFromFunctionIndexSpace): - (JSC::JSWebAssemblyModule::wasmEntrypointCalleeFromFunctionIndexSpace): - (JSC::JSWebAssemblyModule::setJSEntrypointCallee): - (JSC::JSWebAssemblyModule::setWasmEntrypointCallee): - (JSC::JSWebAssemblyModule::allocationSize): - (JSC::JSWebAssemblyModule::calleeFromFunctionIndexSpace): Deleted. - * wasm/js/JSWebAssemblyRuntimeError.h: - * wasm/js/WebAssemblyFunction.cpp: - (JSC::WebAssemblyFunction::call): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyMemoryConstructor.cpp: - (JSC::constructJSWebAssemblyMemory): - * wasm/js/WebAssemblyModuleConstructor.cpp: - (JSC::constructJSWebAssemblyModule): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - -2016-12-11 Filip Pizlo - - Re-enable concurrent GC. - - Rubber stampted by Saam Barati. - - This change actually landed in r209692 by accident. - - * runtime/Options.h: - -2016-12-10 Filip Pizlo - - MarkedBlock::marksConveyLivenessDuringMarking should take into account collection scope - https://bugs.webkit.org/show_bug.cgi?id=165741 - - Reviewed by Saam Barati. - - MarkedBlock::marksConveyLivenessDuringMarking thought that the off-by-one marking - version indicated liveness during any collection when it's just during full collection. - One of its users - MarkedBlock::sweep - knew this and had a special case, but the other - one - MarkedBlock::isLive - didn't. So, I moved the special case into - marksConveyLivenessDuringMarking. - - Also, this cleans up some remaining bitvector races. - - To find this bug, I significantly strengthened our assertions. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * heap/CellContainer.cpp: Added. - (JSC::CellContainer::isNewlyAllocated): - * heap/CellContainer.h: - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::addBlock): - (JSC::MarkedAllocator::removeBlock): - (JSC::MarkedAllocator::dumpBits): - * heap/MarkedAllocator.h: - (JSC::MarkedAllocator::forEachBitVector): - (JSC::MarkedAllocator::forEachBitVectorWithName): - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::tryCreate): - (JSC::MarkedBlock::Handle::~Handle): - (JSC::MarkedBlock::MarkedBlock): - (JSC::MarkedBlock::Handle::specializedSweep): - (JSC::MarkedBlock::Handle::sweepHelperSelectMarksMode): - (JSC::MarkedBlock::Handle::stopAllocating): - (JSC::MarkedBlock::Handle::resumeAllocating): - (JSC::MarkedBlock::aboutToMarkSlow): - (JSC::MarkedBlock::Handle::didConsumeFreeList): - (JSC::MarkedBlock::Handle::dumpState): - * heap/MarkedBlock.h: - (JSC::MarkedBlock::markingVersion): - (JSC::MarkedBlock::isMarkedRaw): - (JSC::MarkedBlock::isMarked): - * heap/MarkedBlockInlines.h: - (JSC::MarkedBlock::marksConveyLivenessDuringMarking): - * heap/SlotVisitor.cpp: - (JSC::SlotVisitor::appendJSCellOrAuxiliary): - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - * runtime/StructureIDTable.h: - (JSC::StructureIDTable::size): - (JSC::StructureIDTable::get): - -2016-12-10 Filip Pizlo - - The DOM should have an advancing wavefront opaque root barrier - https://bugs.webkit.org/show_bug.cgi?id=165712 - - Reviewed by Yusuke Suzuki. - - This exposes the ability to fire an advancing wavefront barrier on opaque roots. It also - gives clients the ability to maintain their own cache of whether that barrier needs to - be enabled. - - The DOM uses this to enable a very cheap barrier on the DOM. This is neutral on - Speedometer and fixes another concurrent GC crash. - - * heap/Heap.cpp: - (JSC::Heap::beginMarking): - (JSC::Heap::endMarking): - (JSC::Heap::writeBarrierOpaqueRootSlow): - (JSC::Heap::addMutatorShouldBeFencedCache): - (JSC::Heap::setMutatorShouldBeFenced): - * heap/Heap.h: - * heap/HeapInlines.h: - (JSC::writeBarrierOpaqueRoot): - -2016-12-10 Commit Queue - - Unreviewed, rolling out r209653, r209654, r209663, and - r209673. - https://bugs.webkit.org/show_bug.cgi?id=165739 - - speedometer crashes (Requested by pizlo on #webkit). - - Reverted changesets: - - "JSVALUE64: Pass arguments in platform argument registers when - making JavaScript calls" - https://bugs.webkit.org/show_bug.cgi?id=160355 - http://trac.webkit.org/changeset/209653 - - "Unreviewed build fix for 32 bit builds." - http://trac.webkit.org/changeset/209654 - - "Unreviewed build fix for the CLOOP after r209653" - http://trac.webkit.org/changeset/209663 - - "REGRESSION(r209653) Crash in CallFrameShuffler::snapshot()" - https://bugs.webkit.org/show_bug.cgi?id=165728 - http://trac.webkit.org/changeset/209673 - -2016-12-10 Michael Saboff - - REGRESSION(r209653) Crash in CallFrameShuffler::snapshot() - https://bugs.webkit.org/show_bug.cgi?id=165728 - - Reviewed by Filip Pizlo. - - It can be the case that a JSValueReg's CachedRecovery is the source for mutliple - GPRs. We only store the CachedRecovery in one slot of m_newRegisters to simplify - the recovery process. This is also done for the case where the recovery source - and destination are the same GPR. - - In light of this change, snapshot needs to be taught that one CacheRecovery is - the source for multiple registers. This is done by using a two step process. - First find all the argument CachedRecovery's and create a vector mapping all of - the target GPRs and the source recovery. Then use that vector to get the - recovery for each register. - - * jit/CallFrameShuffler.h: - (JSC::CallFrameShuffler::snapshot): - -2016-12-10 Keith Miller - - Fix indirect_call if the result type is used. - https://bugs.webkit.org/show_bug.cgi?id=165727 - - Reviewed by Michael Saboff. - - The patchpoint for indirect_call assumed that the callee would be - in params[0]. This is not the case, however, if the callee returns - a value. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::addCallIndirect): - -2016-12-10 Konstantin Tokarev - - [cmake] Include WTF, JSC, and WebCore headers automatically to targers using them - https://bugs.webkit.org/show_bug.cgi?id=165686 + [CMake] Create targets before WEBKIT_INCLUDE_CONFIG_FILES_IF_EXISTS is called + https://bugs.webkit.org/show_bug.cgi?id=174557 Reviewed by Michael Catanzaro. - This change reduces duplication of include path lists between modules, - and reduces future need for fixes like r209605 (broken build because of - WebCore header suddenly becoming used in WebKit2). - * CMakeLists.txt: - * PlatformEfl.cmake: - * PlatformGTK.cmake: - * PlatformJSCOnly.cmake: - * PlatformMac.cmake: -2016-12-10 Michael Saboff +2017-07-14 Yusuke Suzuki - Unreviewed build fix for the CLOOP after r209653 - - * jit/GPRInfo.h: - Provided a definition for NUMBER_OF_JS_FUNCTION_ARGUMENT_REGISTERS when the JIT is disabled. - * jit/JITEntryPoints.h: - Removed #if ENABLE(JIT) protection around contents. - -2016-12-10 Yusuke Suzuki - - [JSC] Module namespace object behaves like immutable prototype exotic object - https://bugs.webkit.org/show_bug.cgi?id=165598 - - Reviewed by Mark Lam. - - In the latest ECMA262 draft, the module namespace object behaves like immutable prototype exotic object. - https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects-setprototypeof-v - - * runtime/JSModuleNamespaceObject.h: - -2016-12-10 Yusuke Suzuki - - REGRESSION(r208791): Assertion in testb3 - https://bugs.webkit.org/show_bug.cgi?id=165651 - - Reviewed by Saam Barati. - - Accidentally we always use edx/rdx for the result of UDiv/UMod. - But it is incorrect. We should use eax/rax for the result of UDiv. - - * b3/B3LowerToAir.cpp: - (JSC::B3::Air::LowerToAir::lowerX86UDiv): - -2016-12-09 Michael Saboff - - Unreviewed build fix for 32 bit builds. - - * dfg/DFGMinifiedNode.h: - (JSC::DFG::MinifiedNode::argumentIndex): Added a static_cast(). - -2016-12-09 Michael Saboff - - JSVALUE64: Pass arguments in platform argument registers when making JavaScript calls - https://bugs.webkit.org/show_bug.cgi?id=160355 - - Reviewed by Filip Pizlo. - - This patch implements passing JavaScript function arguments in registers for 64 bit platforms. - - The implemented convention follows the ABI conventions for the associated platform. - The first two arguments are the callee and argument count, the rest of the argument registers - contain "this" and following argument until all platform argument registers are exhausted. - Arguments beyond what fit in registers are placed on the stack in the same location as - before this patch. - - For X86-64 non-Windows platforms, there are 6 argument registers specified in the related ABI. - ARM64 has had argument registers. This allows for 4 or 6 parameter values to be placed in - registers on these respective platforms. This patch doesn't implement passing arguments in - registers for 32 bit platform, since most platforms have at most 4 argument registers - specified and 32 bit platforms use two 32 bit registers/memory locations to store one JSValue. - - The call frame on the stack in unchanged in format and the arguments that are passed in - registers use the corresponding call frame location as a spill location. Arguments can - also be passed on the stack. The LLInt, baseline JIT'ed code as well as the initial entry - from C++ code base arguments on the stack. DFG s and FTL generated code pass arguments - via registers. All callees can accept arguments either in registers or on the stack. - The callee is responsible for moving argument to its preferred location. - - The multiple entry points to JavaSCript code is now handled via the JITEntryPoints class and - related code. That class now has entries for StackArgsArityCheckNotRequired, - StackArgsMustCheckArity and for platforms that support registers arguments, - RegisterArgsArityCheckNotRequired, RegisterArgsMustCheckArity as well as and additional - RegisterArgsPossibleExtraArgs entry point when extra registers argument are passed. - This last case is needed to spill those extra arguments to the corresponding call frame - slots. - - * JavaScriptCore.xcodeproj/project.pbxproj: - * b3/B3ArgumentRegValue.h: - * b3/B3Validate.cpp: - * bytecode/CallLinkInfo.cpp: - (JSC::CallLinkInfo::CallLinkInfo): - * bytecode/CallLinkInfo.h: - (JSC::CallLinkInfo::setUpCall): - (JSC::CallLinkInfo::argumentsLocation): - (JSC::CallLinkInfo::argumentsInRegisters): - * bytecode/PolymorphicAccess.cpp: - (JSC::AccessCase::generateImpl): - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::executeEffects): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::parseBlock): - * dfg/DFGCPSRethreadingPhase.cpp: - (JSC::DFG::CPSRethreadingPhase::canonicalizeLocalsInBlock): - (JSC::DFG::CPSRethreadingPhase::specialCaseArguments): - (JSC::DFG::CPSRethreadingPhase::computeIsFlushed): - * dfg/DFGClobberize.h: - (JSC::DFG::clobberize): - * dfg/DFGCommon.h: - * dfg/DFGDCEPhase.cpp: - (JSC::DFG::DCEPhase::run): - * dfg/DFGDoesGC.cpp: - (JSC::DFG::doesGC): - * dfg/DFGDriver.cpp: - (JSC::DFG::compileImpl): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGGenerationInfo.h: - (JSC::DFG::GenerationInfo::initArgumentRegisterValue): - * dfg/DFGGraph.cpp: - (JSC::DFG::Graph::dump): - (JSC::DFG::Graph::methodOfGettingAValueProfileFor): - * dfg/DFGGraph.h: - (JSC::DFG::Graph::needsFlushedThis): - (JSC::DFG::Graph::addImmediateShouldSpeculateInt32): - * dfg/DFGInPlaceAbstractState.cpp: - (JSC::DFG::InPlaceAbstractState::initialize): - * dfg/DFGJITCompiler.cpp: - (JSC::DFG::JITCompiler::link): - (JSC::DFG::JITCompiler::compile): - (JSC::DFG::JITCompiler::compileFunction): - (JSC::DFG::JITCompiler::compileEntry): Deleted. - * dfg/DFGJITCompiler.h: - (JSC::DFG::JITCompiler::addJSDirectCall): - (JSC::DFG::JITCompiler::JSDirectCallRecord::JSDirectCallRecord): - (JSC::DFG::JITCompiler::JSDirectCallRecord::hasSlowCall): - * dfg/DFGJITFinalizer.cpp: - (JSC::DFG::JITFinalizer::JITFinalizer): - (JSC::DFG::JITFinalizer::finalize): - (JSC::DFG::JITFinalizer::finalizeFunction): - * dfg/DFGJITFinalizer.h: - * dfg/DFGLiveCatchVariablePreservationPhase.cpp: - (JSC::DFG::LiveCatchVariablePreservationPhase::handleBlock): - * dfg/DFGMaximalFlushInsertionPhase.cpp: - (JSC::DFG::MaximalFlushInsertionPhase::treatRegularBlock): - (JSC::DFG::MaximalFlushInsertionPhase::treatRootBlock): - * dfg/DFGMayExit.cpp: - * dfg/DFGMinifiedNode.cpp: - (JSC::DFG::MinifiedNode::fromNode): - * dfg/DFGMinifiedNode.h: - (JSC::DFG::belongsInMinifiedGraph): - * dfg/DFGNode.cpp: - (JSC::DFG::Node::hasVariableAccessData): - * dfg/DFGNode.h: - (JSC::DFG::Node::accessesStack): - (JSC::DFG::Node::setVariableAccessData): - (JSC::DFG::Node::hasArgumentRegisterIndex): - (JSC::DFG::Node::argumentRegisterIndex): - * dfg/DFGNodeType.h: - * dfg/DFGOSRAvailabilityAnalysisPhase.cpp: - (JSC::DFG::LocalOSRAvailabilityCalculator::executeNode): - * dfg/DFGOSREntrypointCreationPhase.cpp: - (JSC::DFG::OSREntrypointCreationPhase::run): - * dfg/DFGPlan.cpp: - (JSC::DFG::Plan::compileInThreadImpl): - * dfg/DFGPreciseLocalClobberize.h: - (JSC::DFG::PreciseLocalClobberizeAdaptor::readTop): - * dfg/DFGPredictionInjectionPhase.cpp: - (JSC::DFG::PredictionInjectionPhase::run): - * dfg/DFGPredictionPropagationPhase.cpp: - * dfg/DFGPutStackSinkingPhase.cpp: - * dfg/DFGRegisterBank.h: - (JSC::DFG::RegisterBank::iterator::unlock): - (JSC::DFG::RegisterBank::unlockAtIndex): - * dfg/DFGSSAConversionPhase.cpp: - (JSC::DFG::SSAConversionPhase::run): - * dfg/DFGSafeToExecute.h: - (JSC::DFG::safeToExecute): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::SpeculativeJIT): - (JSC::DFG::SpeculativeJIT::clearGenerationInfo): - (JSC::DFG::dumpRegisterInfo): - (JSC::DFG::SpeculativeJIT::dump): - (JSC::DFG::SpeculativeJIT::compileCurrentBlock): - (JSC::DFG::SpeculativeJIT::checkArgumentTypes): - (JSC::DFG::SpeculativeJIT::setupArgumentRegistersForEntry): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT.h: - (JSC::DFG::SpeculativeJIT::allocate): - (JSC::DFG::SpeculativeJIT::spill): - (JSC::DFG::SpeculativeJIT::generationInfoFromVirtualRegister): - (JSC::DFG::JSValueOperand::JSValueOperand): - (JSC::DFG::JSValueOperand::gprUseSpecific): - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::emitCall): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::fillJSValue): - (JSC::DFG::SpeculativeJIT::emitCall): - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStrengthReductionPhase.cpp: - (JSC::DFG::StrengthReductionPhase::handleNode): - * dfg/DFGThunks.cpp: - (JSC::DFG::osrEntryThunkGenerator): - * dfg/DFGVariableEventStream.cpp: - (JSC::DFG::VariableEventStream::reconstruct): - * dfg/DFGVirtualRegisterAllocationPhase.cpp: - (JSC::DFG::VirtualRegisterAllocationPhase::allocateRegister): - (JSC::DFG::VirtualRegisterAllocationPhase::run): - * ftl/FTLCapabilities.cpp: - (JSC::FTL::canCompile): - * ftl/FTLJITCode.cpp: - (JSC::FTL::JITCode::~JITCode): - (JSC::FTL::JITCode::initializeEntrypointThunk): - (JSC::FTL::JITCode::setEntryFor): - (JSC::FTL::JITCode::addressForCall): - (JSC::FTL::JITCode::executableAddressAtOffset): - (JSC::FTL::JITCode::initializeAddressForCall): Deleted. - (JSC::FTL::JITCode::initializeArityCheckEntrypoint): Deleted. - * ftl/FTLJITCode.h: - * ftl/FTLJITFinalizer.cpp: - (JSC::FTL::JITFinalizer::finalizeFunction): - * ftl/FTLLink.cpp: - (JSC::FTL::link): - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::lower): - (JSC::FTL::DFG::LowerDFGToB3::compileNode): - (JSC::FTL::DFG::LowerDFGToB3::compileGetArgumentRegister): - (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstruct): - (JSC::FTL::DFG::LowerDFGToB3::compileDirectCallOrConstruct): - (JSC::FTL::DFG::LowerDFGToB3::compileTailCall): - (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargsSpread): - (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargs): - (JSC::FTL::DFG::LowerDFGToB3::compileCallEval): - * ftl/FTLOSREntry.cpp: - (JSC::FTL::prepareOSREntry): - * ftl/FTLOutput.cpp: - (JSC::FTL::Output::argumentRegister): - (JSC::FTL::Output::argumentRegisterInt32): - * ftl/FTLOutput.h: - * interpreter/ShadowChicken.cpp: - (JSC::ShadowChicken::update): - * jit/AssemblyHelpers.cpp: - (JSC::AssemblyHelpers::emitDumbVirtualCall): - * jit/AssemblyHelpers.h: - (JSC::AssemblyHelpers::spillArgumentRegistersToFrameBeforePrologue): - (JSC::AssemblyHelpers::spillArgumentRegistersToFrame): - (JSC::AssemblyHelpers::fillArgumentRegistersFromFrameBeforePrologue): - (JSC::AssemblyHelpers::emitPutArgumentToCallFrameBeforePrologue): - (JSC::AssemblyHelpers::emitPutArgumentToCallFrame): - (JSC::AssemblyHelpers::emitGetFromCallFrameHeaderBeforePrologue): - (JSC::AssemblyHelpers::emitGetFromCallFrameArgumentBeforePrologue): - (JSC::AssemblyHelpers::emitGetPayloadFromCallFrameHeaderBeforePrologue): - (JSC::AssemblyHelpers::incrementCounter): - * jit/CachedRecovery.cpp: - (JSC::CachedRecovery::addTargetJSValueRegs): - * jit/CachedRecovery.h: - (JSC::CachedRecovery::gprTargets): - (JSC::CachedRecovery::setWantedFPR): - (JSC::CachedRecovery::wantedJSValueRegs): - (JSC::CachedRecovery::setWantedJSValueRegs): Deleted. - * jit/CallFrameShuffleData.h: - * jit/CallFrameShuffler.cpp: - (JSC::CallFrameShuffler::CallFrameShuffler): - (JSC::CallFrameShuffler::dump): - (JSC::CallFrameShuffler::tryWrites): - (JSC::CallFrameShuffler::prepareAny): - * jit/CallFrameShuffler.h: - (JSC::CallFrameShuffler::snapshot): - (JSC::CallFrameShuffler::addNew): - (JSC::CallFrameShuffler::initDangerFrontier): - (JSC::CallFrameShuffler::updateDangerFrontier): - (JSC::CallFrameShuffler::findDangerFrontierFrom): - * jit/CallFrameShuffler64.cpp: - (JSC::CallFrameShuffler::emitDisplace): - * jit/GPRInfo.h: - (JSC::JSValueRegs::operator==): - (JSC::JSValueRegs::operator!=): - (JSC::GPRInfo::toArgumentIndex): - (JSC::argumentRegisterFor): - (JSC::argumentRegisterForCallee): - (JSC::argumentRegisterForArgumentCount): - (JSC::argumentRegisterIndexForJSFunctionArgument): - (JSC::jsFunctionArgumentForArgumentRegister): - (JSC::argumentRegisterForFunctionArgument): - (JSC::numberOfRegisterArgumentsFor): - * jit/JIT.cpp: - (JSC::JIT::compileWithoutLinking): - (JSC::JIT::link): - (JSC::JIT::compileCTINativeCall): Deleted. - * jit/JIT.h: - (JSC::JIT::compileNativeCallEntryPoints): - * jit/JITCall.cpp: - (JSC::JIT::compileSetupVarargsFrame): - (JSC::JIT::compileCallEval): - (JSC::JIT::compileCallEvalSlowCase): - (JSC::JIT::compileOpCall): - (JSC::JIT::compileOpCallSlowCase): - * jit/JITCall32_64.cpp: - (JSC::JIT::compileCallEvalSlowCase): - (JSC::JIT::compileOpCall): - (JSC::JIT::compileOpCallSlowCase): - * jit/JITCode.cpp: - (JSC::JITCode::execute): - (JSC::DirectJITCode::DirectJITCode): - (JSC::DirectJITCode::initializeEntryPoints): - (JSC::DirectJITCode::addressForCall): - (JSC::NativeJITCode::addressForCall): - (JSC::DirectJITCode::initializeCodeRef): Deleted. - * jit/JITCode.h: - (JSC::JITCode::executableAddress): Deleted. - * jit/JITEntryPoints.h: Added. - (JSC::JITEntryPoints::JITEntryPoints): - (JSC::JITEntryPoints::entryFor): - (JSC::JITEntryPoints::setEntryFor): - (JSC::JITEntryPoints::offsetOfEntryFor): - (JSC::JITEntryPoints::registerEntryTypeForArgumentCount): - (JSC::JITEntryPoints::registerEntryTypeForArgumentType): - (JSC::JITEntryPoints::clearEntries): - (JSC::JITEntryPoints::operator=): - (JSC::JITEntryPointsWithRef::JITEntryPointsWithRef): - (JSC::JITEntryPointsWithRef::codeRef): - (JSC::argumentsLocationFor): - (JSC::registerEntryPointTypeFor): - (JSC::entryPointTypeFor): - (JSC::thunkEntryPointTypeFor): - (JSC::JITJSCallThunkEntryPointsWithRef::JITJSCallThunkEntryPointsWithRef): - (JSC::JITJSCallThunkEntryPointsWithRef::entryFor): - (JSC::JITJSCallThunkEntryPointsWithRef::setEntryFor): - (JSC::JITJSCallThunkEntryPointsWithRef::offsetOfEntryFor): - (JSC::JITJSCallThunkEntryPointsWithRef::clearEntries): - (JSC::JITJSCallThunkEntryPointsWithRef::codeRef): - (JSC::JITJSCallThunkEntryPointsWithRef::operator=): - * jit/JITOpcodes.cpp: - (JSC::JIT::privateCompileJITEntryNativeCall): - (JSC::JIT::privateCompileCTINativeCall): Deleted. - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::privateCompileJITEntryNativeCall): - (JSC::JIT::privateCompileCTINativeCall): Deleted. - * jit/JITOperations.cpp: - * jit/JITThunks.cpp: - (JSC::JITThunks::jitEntryNativeCall): - (JSC::JITThunks::jitEntryNativeConstruct): - (JSC::JITThunks::jitEntryStub): - (JSC::JITThunks::jitCallThunkEntryStub): - (JSC::JITThunks::hostFunctionStub): - (JSC::JITThunks::ctiNativeCall): Deleted. - (JSC::JITThunks::ctiNativeConstruct): Deleted. - * jit/JITThunks.h: - * jit/JSInterfaceJIT.h: - (JSC::JSInterfaceJIT::emitJumpIfNotInt32): - (JSC::JSInterfaceJIT::emitLoadInt32): - * jit/RegisterSet.cpp: - (JSC::RegisterSet::argumentRegisters): - * jit/RegisterSet.h: - * jit/Repatch.cpp: - (JSC::linkSlowFor): - (JSC::revertCall): - (JSC::unlinkFor): - (JSC::linkVirtualFor): - (JSC::linkPolymorphicCall): - * jit/SpecializedThunkJIT.h: - (JSC::SpecializedThunkJIT::SpecializedThunkJIT): - (JSC::SpecializedThunkJIT::checkJSStringArgument): - (JSC::SpecializedThunkJIT::linkFailureHere): - (JSC::SpecializedThunkJIT::finalize): - * jit/ThunkGenerator.h: - * jit/ThunkGenerators.cpp: - (JSC::createRegisterArgumentsSpillEntry): - (JSC::slowPathFor): - (JSC::linkCallThunkGenerator): - (JSC::linkDirectCallThunkGenerator): - (JSC::linkPolymorphicCallThunkGenerator): - (JSC::virtualThunkFor): - (JSC::nativeForGenerator): - (JSC::nativeCallGenerator): - (JSC::nativeTailCallGenerator): - (JSC::nativeTailCallWithoutSavedTagsGenerator): - (JSC::nativeConstructGenerator): - (JSC::stringCharLoadRegCall): - (JSC::charCodeAtThunkGenerator): - (JSC::charAtThunkGenerator): - (JSC::fromCharCodeThunkGenerator): - (JSC::clz32ThunkGenerator): - (JSC::sqrtThunkGenerator): - (JSC::floorThunkGenerator): - (JSC::ceilThunkGenerator): - (JSC::truncThunkGenerator): - (JSC::roundThunkGenerator): - (JSC::expThunkGenerator): - (JSC::logThunkGenerator): - (JSC::absThunkGenerator): - (JSC::imulThunkGenerator): - (JSC::randomThunkGenerator): - (JSC::boundThisNoArgsFunctionCallGenerator): - * jit/ThunkGenerators.h: - * jsc.cpp: - (jscmain): - * llint/LLIntEntrypoint.cpp: - (JSC::LLInt::setFunctionEntrypoint): - (JSC::LLInt::setEvalEntrypoint): - (JSC::LLInt::setProgramEntrypoint): - (JSC::LLInt::setModuleProgramEntrypoint): - * llint/LLIntSlowPaths.cpp: - (JSC::LLInt::entryOSR): - (JSC::LLInt::setUpCall): - * llint/LLIntThunks.cpp: - (JSC::LLInt::generateThunkWithJumpTo): - (JSC::LLInt::functionForRegisterCallEntryThunkGenerator): - (JSC::LLInt::functionForStackCallEntryThunkGenerator): - (JSC::LLInt::functionForRegisterConstructEntryThunkGenerator): - (JSC::LLInt::functionForStackConstructEntryThunkGenerator): - (JSC::LLInt::functionForRegisterCallArityCheckThunkGenerator): - (JSC::LLInt::functionForStackCallArityCheckThunkGenerator): - (JSC::LLInt::functionForRegisterConstructArityCheckThunkGenerator): - (JSC::LLInt::functionForStackConstructArityCheckThunkGenerator): - (JSC::LLInt::functionForCallEntryThunkGenerator): Deleted. - (JSC::LLInt::functionForConstructEntryThunkGenerator): Deleted. - (JSC::LLInt::functionForCallArityCheckThunkGenerator): Deleted. - (JSC::LLInt::functionForConstructArityCheckThunkGenerator): Deleted. - * llint/LLIntThunks.h: - * runtime/ArityCheckMode.h: - * runtime/ExecutableBase.cpp: - (JSC::ExecutableBase::clearCode): - * runtime/ExecutableBase.h: - (JSC::ExecutableBase::entrypointFor): - (JSC::ExecutableBase::offsetOfEntryFor): - (JSC::ExecutableBase::offsetOfJITCodeWithArityCheckFor): Deleted. - * runtime/JSBoundFunction.cpp: - (JSC::boundThisNoArgsFunctionCall): - * runtime/NativeExecutable.cpp: - (JSC::NativeExecutable::finishCreation): - * runtime/ScriptExecutable.cpp: - (JSC::ScriptExecutable::installCode): - * runtime/VM.cpp: - (JSC::VM::VM): - (JSC::thunkGeneratorForIntrinsic): - (JSC::VM::clearCounters): - (JSC::VM::dumpCounters): - * runtime/VM.h: - (JSC::VM::getJITEntryStub): - (JSC::VM::getJITCallThunkEntryStub): - (JSC::VM::addressOfCounter): - (JSC::VM::counterFor): - * wasm/WasmBinding.cpp: - (JSC::Wasm::importStubGenerator): - -2016-12-09 Keith Miller - - Wasm should support call_indirect - https://bugs.webkit.org/show_bug.cgi?id=165718 - - Reviewed by Filip Pizlo. - - This patch adds support for call_indirect. The basic framework for - an indirect call is that the module holds a buffer containing a - stub for each function in the index space. Whenever a function - needs to do an indirect call it gets a index into that table. In - order to ensure call_indirect is calling a valid function the - functionIndexSpace also needs a pointer to a canonicalized - signature. When making an indirect call, we first check the index - is in range, then check the signature matches the value we were given. - - This patch also differentiates between FunctionIndexSpaces and - ImmutableFunctionIndexSpaces. Since we don't know the size of the - FunctionIndexSpace when we start parsing we need to be able to - resize the IndexSpace. However, once we have finished parsing all - the sections we want to prevent an relocation of the function - index space pointer. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::B3IRGenerator::addCall): - (JSC::Wasm::B3IRGenerator::addCallIndirect): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmB3IRGenerator.h: - * wasm/WasmCallingConvention.h: - (JSC::Wasm::CallingConvention::setupCall): - * wasm/WasmFormat.h: - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::setErrorMessage): - (JSC::Wasm::FunctionParser::FunctionParser): - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::run): - * wasm/WasmPlan.h: - (JSC::Wasm::Plan::takeFunctionIndexSpace): - * wasm/WasmValidate.cpp: - (JSC::Wasm::Validate::addCallIndirect): - (JSC::Wasm::validateFunction): - * wasm/WasmValidate.h: - * wasm/js/JSWebAssemblyModule.cpp: - (JSC::JSWebAssemblyModule::create): - (JSC::JSWebAssemblyModule::JSWebAssemblyModule): - * wasm/js/JSWebAssemblyModule.h: - (JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace): - (JSC::JSWebAssemblyModule::offsetOfFunctionIndexSpace): - -2016-12-09 JF Bastien - - WebAssembly: implement data section - https://bugs.webkit.org/show_bug.cgi?id=165696 - - Reviewed by Keith Miller. - - As specified in https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#data-section - Note that some of the interesting corner cases are ill-defined by the spec: https://github.com/WebAssembly/design/issues/897 - - * wasm/WasmFormat.h: segments are what represent sections of memory to initialize (similar to ELF's non-zero intializer data / rodata) - (JSC::Wasm::Segment::make): - (JSC::Wasm::Segment::destroy): - (JSC::Wasm::Segment::byte): - (JSC::Wasm::Segment::makePtr): - * wasm/WasmModuleParser.cpp: parse the data section, and prevent a few overflows if a user passes in UINT_MAX (the loops would overflow) - (JSC::Wasm::ModuleParser::parseType): - (JSC::Wasm::ModuleParser::parseImport): - (JSC::Wasm::ModuleParser::parseFunction): - (JSC::Wasm::ModuleParser::parseExport): - (JSC::Wasm::ModuleParser::parseCode): - (JSC::Wasm::ModuleParser::parseData): - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::evaluate): the only sensible time to initialize the data section is after linking, but before calling start, I test for this but the spec isn't clear it's correct yet - -2016-12-09 Karim H - - It is okay to turn undefined into null because we are producing values for a - JSON representation (InspectorValue) and JSON has a `null` value and no - `undefined` value. - https://bugs.webkit.org/show_bug.cgi?id=165506 - - Reviewed by Darin Adler. - - * bindings/ScriptValue.cpp: - (Inspector::jsToInspectorValue): - -2016-12-09 Filip Pizlo - - REGRESSION (r209554-209571): stress/poly-setter-combo crashing - https://bugs.webkit.org/show_bug.cgi?id=165669 - - Reviewed by Geoffrey Garen. - - We now rely on objects being zero-filled in a bunch of places, not just concurrent GC. - So, we need 32-bit to do it too. - - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * jit/JITOpcodes32_64.cpp: - (JSC::JIT::emit_op_new_object): - -2016-12-09 Eric Carlson - - Annotate MediaStream and WebRTC idl with EnabledAtRuntime flag - https://bugs.webkit.org/show_bug.cgi?id=165251 - - Reviewed by Dean Jackson. - - Based on a patch by Dr Alex Gouaillard - - * runtime/CommonIdentifiers.h: Add WebRTC and MediaStream identifiers. - -2016-12-09 JF Bastien - - WebAssembly JS API: implement start function - https://bugs.webkit.org/show_bug.cgi?id=165150 - - Reviewed by Saam Barati. - - * wasm/WasmFormat.h: pass the start function around - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseTable): mark unreachable code - (JSC::Wasm::ModuleParser::parseGlobal): mark unreachable code - (JSC::Wasm::ModuleParser::parseStart): mark unreachable code - (JSC::Wasm::ModuleParser::parseElement): mark unreachable code - (JSC::Wasm::ModuleParser::parseData): mark unreachable code - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): NFC: call the new function below - (JSC::WebAssemblyFunction::call): separate this out so that the start function can use it - * wasm/js/WebAssemblyFunction.h: - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::visitChildren): visit the start function - (JSC::WebAssemblyModuleRecord::link): handle start function - (JSC::WebAssemblyModuleRecord::evaluate): call the start function, if present - * wasm/js/WebAssemblyModuleRecord.h: - -2016-12-09 Filip Pizlo - - GC might be forced to look at a nuked object due to ordering of AllocatePropertyStorage, MaterializeNewObject, and PutStructure - https://bugs.webkit.org/show_bug.cgi?id=165672 - - Reviewed by Geoffrey Garen. - - We need to make sure that the shady stuff in a property put happens after the - PutByOffset, since the PutByOffset is the place where we materialize. More generally, we - should strive to not have any fenceposts between Nodes where a GC would be illegal. - - This gets us most of the way there by separating NukeStructureAndSetButterfly from - [Re]AllocatePropertyStorage. A transitioning put will now look something like: - - GetButterfly - ReallocatePropertyStorage - PutByOffset - NukeStructureAndSetButterfly - PutStructure - - Previously the structure would get nuked by ReallocatePropertyStorage, so if we placed - an object materialization just after it (before the PutByOffset) then any GC that - completed at that safepoint would encounter an unresolved visit race due to seeing a - nuked structure. We cannot have nuked structures at safepoints, and this change makes - sure that we don't - at least until someone tries to sink to the PutStructure. We will - eventually have to create a combined SetStructureAndButterfly node, but we don't need it - yet. - - This also fixes a goof where the DFG's AllocatePropertyStorage was nulling the structure - instead of nuking it. This could easily have caused many crashes in GC. - - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::executeEffects): - * dfg/DFGByteCodeParser.cpp: - (JSC::DFG::ByteCodeParser::handlePutById): - * dfg/DFGClobberize.h: - (JSC::DFG::clobberize): - * dfg/DFGClobbersExitState.cpp: - (JSC::DFG::clobbersExitState): - * dfg/DFGConstantFoldingPhase.cpp: - (JSC::DFG::ConstantFoldingPhase::emitPutByOffset): - * dfg/DFGDoesGC.cpp: - (JSC::DFG::doesGC): - * dfg/DFGFixupPhase.cpp: - (JSC::DFG::FixupPhase::fixupNode): - * dfg/DFGMayExit.cpp: - * dfg/DFGNodeType.h: - * dfg/DFGOperations.cpp: - * dfg/DFGOperations.h: - * dfg/DFGPredictionPropagationPhase.cpp: - * dfg/DFGSafeToExecute.h: - (JSC::DFG::safeToExecute): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileNukeStructureAndSetButterfly): - * dfg/DFGSpeculativeJIT.h: - * dfg/DFGSpeculativeJIT32_64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGSpeculativeJIT64.cpp: - (JSC::DFG::SpeculativeJIT::compile): - * dfg/DFGStoreBarrierInsertionPhase.cpp: - * dfg/DFGTypeCheckHoistingPhase.cpp: - (JSC::DFG::TypeCheckHoistingPhase::identifyRedundantStructureChecks): - * ftl/FTLCapabilities.cpp: - (JSC::FTL::canCompile): - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::compileNode): - (JSC::FTL::DFG::LowerDFGToB3::compileNukeStructureAndSetButterfly): - (JSC::FTL::DFG::LowerDFGToB3::storageForTransition): - (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::reallocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorageWithSizeImpl): - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - * runtime/Options.h: Fix a bug - make it possible to turn on concurrent GC optionally again. - -2016-12-09 Chris Dumez - - Inline JSCell::toObject() - https://bugs.webkit.org/show_bug.cgi?id=165679 - - Reviewed by Geoffrey Garen. - - Inline JSCell::toObject() as it shows on Speedometer profiles. - - * runtime/JSCell.cpp: - (JSC::JSCell::toObjectSlow): - (JSC::JSCell::toObject): Deleted. - * runtime/JSCell.h: - * runtime/JSCellInlines.h: - (JSC::JSCell::toObject): - -2016-12-09 Geoffrey Garen - - Deploy OrdinalNumber in JSC::SourceCode - https://bugs.webkit.org/show_bug.cgi?id=165687 - - Reviewed by Michael Saboff. - - We have a lot of confusion between 1-based and 0-based counting in line - and column numbers. Let's use OrdinalNumber to clear up the confusion. - - * bytecode/UnlinkedFunctionExecutable.cpp: - (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): - (JSC::UnlinkedFunctionExecutable::link): - * bytecompiler/BytecodeGenerator.h: - (JSC::BytecodeGenerator::emitExpressionInfo): - * inspector/JSInjectedScriptHost.cpp: - (Inspector::JSInjectedScriptHost::functionDetails): - * parser/Lexer.cpp: - (JSC::Lexer::setCode): - * parser/Parser.cpp: - (JSC::Parser::Parser): - * parser/Parser.h: - (JSC::Parser::parse): - * parser/SourceCode.h: - (JSC::SourceCode::SourceCode): - (JSC::SourceCode::firstLine): - (JSC::SourceCode::startColumn): - * runtime/CodeCache.cpp: - (JSC::CodeCache::getUnlinkedGlobalCodeBlock): - * runtime/ScriptExecutable.h: - (JSC::ScriptExecutable::firstLine): - (JSC::ScriptExecutable::startColumn): - * tools/CodeProfile.h: - (JSC::CodeProfile::CodeProfile): - -2016-12-09 Saam Barati - - WebAssembly JS API: implement importing and defining Memory - https://bugs.webkit.org/show_bug.cgi?id=164134 - - Reviewed by Keith Miller. - - This patch implements the WebAssembly.Memory object. It refactors - the code to now associate a Memory with the instance instead of - the Module. - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * jsc.cpp: - (functionTestWasmModuleFunctions): - * runtime/VM.h: - * shell/CMakeLists.txt: - * testWasm.cpp: Removed. - This has bitrotted. I'm removing it. - - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): - (JSC::Wasm::sizeOfLoadOp): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): - * wasm/WasmB3IRGenerator.h: - * wasm/WasmFormat.cpp: - (JSC::Wasm::ModuleInformation::~ModuleInformation): Deleted. - * wasm/WasmFormat.h: - * wasm/WasmMemory.cpp: - (JSC::Wasm::Memory::Memory): - * wasm/WasmMemory.h: - (JSC::Wasm::Memory::size): - (JSC::Wasm::Memory::initial): - (JSC::Wasm::Memory::maximum): - (JSC::Wasm::Memory::pinnedRegisters): Deleted. - * wasm/WasmMemoryInformation.cpp: Added. - (JSC::Wasm::MemoryInformation::MemoryInformation): - * wasm/WasmMemoryInformation.h: Added. - (JSC::Wasm::MemoryInformation::MemoryInformation): - (JSC::Wasm::MemoryInformation::pinnedRegisters): - (JSC::Wasm::MemoryInformation::initial): - (JSC::Wasm::MemoryInformation::maximum): - (JSC::Wasm::MemoryInformation::isImport): - (JSC::Wasm::MemoryInformation::operator bool): - * wasm/WasmModuleParser.cpp: - (JSC::Wasm::ModuleParser::parseImport): - (JSC::Wasm::ModuleParser::parseMemoryHelper): - (JSC::Wasm::ModuleParser::parseMemory): - (JSC::Wasm::ModuleParser::parseExport): - * wasm/WasmModuleParser.h: - * wasm/WasmPageCount.h: Added. Implement a new way of describing Wasm - pages and then asking for how many bytes a quantity of pages is. This - class also makes it clear when we're talking about bytes or pages. - - (JSC::Wasm::PageCount::PageCount): - (JSC::Wasm::PageCount::bytes): - (JSC::Wasm::PageCount::isValid): - (JSC::Wasm::PageCount::max): - (JSC::Wasm::PageCount::operator bool): - (JSC::Wasm::PageCount::operator<): - (JSC::Wasm::PageCount::operator>): - (JSC::Wasm::PageCount::operator>=): - * wasm/WasmPlan.cpp: - (JSC::Wasm::Plan::run): - * wasm/WasmPlan.h: - (JSC::Wasm::Plan::memory): Deleted. - * wasm/WasmValidate.cpp: - (JSC::Wasm::Validate::hasMemory): - (JSC::Wasm::Validate::Validate): - (JSC::Wasm::validateFunction): - * wasm/WasmValidate.h: - * wasm/generateWasmValidateInlinesHeader.py: - * wasm/js/JSWebAssemblyInstance.cpp: - (JSC::JSWebAssemblyInstance::visitChildren): - * wasm/js/JSWebAssemblyInstance.h: - (JSC::JSWebAssemblyInstance::memory): - (JSC::JSWebAssemblyInstance::setMemory): - (JSC::JSWebAssemblyInstance::offsetOfImportFunctions): - (JSC::JSWebAssemblyInstance::allocationSize): - * wasm/js/JSWebAssemblyMemory.cpp: - (JSC::JSWebAssemblyMemory::create): - (JSC::JSWebAssemblyMemory::JSWebAssemblyMemory): - (JSC::JSWebAssemblyMemory::buffer): - (JSC::JSWebAssemblyMemory::visitChildren): - * wasm/js/JSWebAssemblyMemory.h: - (JSC::JSWebAssemblyMemory::memory): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - Handle importing and creating of memory according - to the spec. This also does the needed validation - of making sure the memory defined in the module - is compatible with the imported memory. - - (JSC::constructJSWebAssemblyInstance): - * wasm/js/WebAssemblyMemoryConstructor.cpp: - (JSC::constructJSWebAssemblyMemory): - (JSC::callJSWebAssemblyMemory): - * wasm/js/WebAssemblyMemoryPrototype.cpp: - (JSC::webAssemblyMemoryProtoFuncBuffer): - (JSC::WebAssemblyMemoryPrototype::create): - (JSC::WebAssemblyMemoryPrototype::finishCreation): - * wasm/js/WebAssemblyMemoryPrototype.h: - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::finishCreation): - (JSC::WebAssemblyModuleRecord::link): - -2016-12-09 Joseph Pecoraro - - Web Inspector: Some resources fetched via Fetch API do not have data - https://bugs.webkit.org/show_bug.cgi?id=165230 - + [WTF] Use std::unique_ptr for StackTrace + https://bugs.webkit.org/show_bug.cgi?id=174495 Reviewed by Alex Christensen. - * inspector/protocol/Page.json: - Add new Fetch Page.ResourceType. - -2016-12-09 Geoffrey Garen - - TextPosition and OrdinalNumber should be more like idiomatic numbers - https://bugs.webkit.org/show_bug.cgi?id=165678 - - Reviewed by Filip Pizlo. - - Adopt default constructor. - - * API/JSBase.cpp: - (JSEvaluateScript): - (JSCheckScriptSyntax): - * API/JSObjectRef.cpp: - (JSObjectMakeFunction): - * API/JSScriptRef.cpp: - (OpaqueJSScript::OpaqueJSScript): - * jsc.cpp: - (functionCheckModuleSyntax): - * parser/SourceCode.h: - (JSC::makeSource): - * parser/SourceProvider.h: - (JSC::StringSourceProvider::create): - (JSC::WebAssemblySourceProvider::WebAssemblySourceProvider): - * runtime/FunctionConstructor.cpp: - (JSC::constructFunction): - * runtime/ModuleLoaderPrototype.cpp: - (JSC::moduleLoaderPrototypeParseModule): - -2016-12-09 Filip Pizlo - - Unreviewed, disable concurrent GC for real. - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - -2016-12-09 Filip Pizlo - - Unreviewed, disable concurrent GC while crashes get investigated. - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - -2016-12-09 Filip Pizlo - - JSSegmentedVariableObject should keep its state private - - Rubber stamped by Michael Saboff. - - Its state fields were protected for no reason. They really should be private because - you have to know to obey a particular concurrency protocol when accessing them. - - * runtime/JSSegmentedVariableObject.h: - -2016-12-09 Csaba Osztrogonác - - Unreviewed ARM buildfix after 209570. - - * assembler/MacroAssemblerARM.h: - (JSC::MacroAssemblerARM::or32): Added. - -2016-12-08 JF Bastien - - WebAssembly: JSC::link* shouldn't need a CodeBlock - https://bugs.webkit.org/show_bug.cgi?id=165591 - - Reviewed by Keith Miller. - - Allow linking without a CodeBlock, which WebAssembly's wasm -> JS stubs does. This needs to work for polymorphic and virtual calls. This patch adds corresponding tests for this. - - * assembler/LinkBuffer.cpp: - (JSC::shouldDumpDisassemblyFor): don't look at the tier option if there isn't a CodeBlock, only look at the global one. This is a WebAssembly function, so the tier information is irrelevant. - * jit/Repatch.cpp: - (JSC::isWebAssemblyToJSCallee): this is used in the link* functions below - (JSC::linkFor): - (JSC::linkVirtualFor): - (JSC::linkPolymorphicCall): - * runtime/Options.h: add an option to change the maximum number of polymorphic calls in stubs from wasm to JS, which will come in handy when we try to tune performance or try merging some of the WebAssembly stubs - * wasm/WasmBinding.cpp: - (JSC::Wasm::importStubGenerator): remove the breakpoint since the code now works - * wasm/js/WebAssemblyToJSCallee.h: - -2016-12-08 Filip Pizlo - - MultiPutByOffset should get a barrier if it transitions - https://bugs.webkit.org/show_bug.cgi?id=165646 - - Reviewed by Keith Miller. - - Previously, if we knew that we were storing a non-cell but we needed to transition, we - would fail to add the barrier but the FTL's lowering expected the barrier to be there. - - Strictly, we need to "consider" the barrier on MultiPutByOffset if the value is - possibly a cell or if the MultiPutByOffset may transition. Then "considering" the - barrier implies checking if the base is possibly old. - - But because the barrier is so cheap anyway, this patch implements something safer: we - just consider the barrier on MultiPutByOffset unconditionally, which opts it out of any - barrier optimizations other than those based on the predicted state of the base. Those - optimizations are already sound - for example they use doesGC() to detect safepoints - and that function correctly predicts when MultiPutByOffset could GC. - - Because the barrier optimizations are only a very small speed-up, I think it's great to - fix bugs by weakening the optimizer without cleverness. - - * dfg/DFGFixupPhase.cpp: - * dfg/DFGStoreBarrierInsertionPhase.cpp: - * heap/MarkedBlock.cpp: - (JSC::MarkedBlock::assertValidCell): - -2016-12-08 Filip Pizlo - - Enable concurrent GC on ARM64 - https://bugs.webkit.org/show_bug.cgi?id=165643 - - Reviewed by Saam Barati. - - It looks stable enough to enable. - - * assembler/CPU.h: - (JSC::useGCFences): Deleted. - * bytecode/PolymorphicAccess.cpp: - (JSC::AccessCase::generateImpl): - * dfg/DFGSpeculativeJIT.cpp: - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - * ftl/FTLLowerDFGToB3.cpp: - (JSC::FTL::DFG::LowerDFGToB3::compileMaterializeNewObject): - (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::reallocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::allocateObject): - * jit/AssemblyHelpers.h: - (JSC::AssemblyHelpers::mutatorFence): - (JSC::AssemblyHelpers::storeButterfly): - (JSC::AssemblyHelpers::nukeStructureAndStoreButterfly): - (JSC::AssemblyHelpers::emitInitializeInlineStorage): - (JSC::AssemblyHelpers::emitInitializeOutOfLineStorage): - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - -2016-12-08 Filip Pizlo - - Disable collectContinuously if not useConcurrentGC - - Rubber stamped by Geoffrey Garen. - - * runtime/Options.cpp: - (JSC::recomputeDependentOptions): - -2016-12-08 Filip Pizlo - - Unreviewed, fix cloop build. - - * runtime/JSObject.h: - -2016-12-06 Filip Pizlo - - Concurrent GC should be stable enough to land enabled on X86_64 - https://bugs.webkit.org/show_bug.cgi?id=164990 - - Reviewed by Geoffrey Garen. - - This fixes a ton of performance and correctness bugs revealed by getting the concurrent GC to - be stable enough to land enabled. - - I had to redo the JSObject::visitChildren concurrency protocol again. This time I think it's - even more correct than ever! - - This is an enormous win on JetStream/splay-latency and Octane/SplayLatency. It looks to be - mostly neutral on everything else, though Speedometer is showing statistically weak signs of a - slight regression. - - * API/JSAPIWrapperObject.mm: Added locking. - (JSC::JSAPIWrapperObject::visitChildren): - * API/JSCallbackObject.h: Added locking. - (JSC::JSCallbackObjectData::visitChildren): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty): - (JSC::JSCallbackObjectData::JSPrivatePropertyMap::visitChildren): - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * bytecode/CodeBlock.cpp: - (JSC::CodeBlock::UnconditionalFinalizer::finalizeUnconditionally): This had a TOCTOU race on shouldJettisonDueToOldAge. - (JSC::EvalCodeCache::visitAggregate): Moved to EvalCodeCache.cpp. - * bytecode/DirectEvalCodeCache.cpp: Added. Outlined some functions and made them use locks. - (JSC::DirectEvalCodeCache::setSlow): - (JSC::DirectEvalCodeCache::clear): - (JSC::DirectEvalCodeCache::visitAggregate): - * bytecode/DirectEvalCodeCache.h: - (JSC::DirectEvalCodeCache::set): - (JSC::DirectEvalCodeCache::clear): Deleted. - * bytecode/UnlinkedCodeBlock.cpp: Added locking. - (JSC::UnlinkedCodeBlock::visitChildren): - (JSC::UnlinkedCodeBlock::setInstructions): - (JSC::UnlinkedCodeBlock::shrinkToFit): - * bytecode/UnlinkedCodeBlock.h: Added locking. - (JSC::UnlinkedCodeBlock::addRegExp): - (JSC::UnlinkedCodeBlock::addConstant): - (JSC::UnlinkedCodeBlock::addFunctionDecl): - (JSC::UnlinkedCodeBlock::addFunctionExpr): - (JSC::UnlinkedCodeBlock::createRareDataIfNecessary): - (JSC::UnlinkedCodeBlock::shrinkToFit): Deleted. - * debugger/Debugger.cpp: Use the right delete API. - (JSC::Debugger::recompileAllJSFunctions): - * dfg/DFGAbstractInterpreterInlines.h: - (JSC::DFG::AbstractInterpreter::executeEffects): Fix a pre-existing bug in ToFunction constant folding. - * dfg/DFGClobberize.h: Add support for nuking. - (JSC::DFG::clobberize): - * dfg/DFGClobbersExitState.cpp: Add support for nuking. - (JSC::DFG::clobbersExitState): - * dfg/DFGFixupPhase.cpp: Add support for nuking. - (JSC::DFG::FixupPhase::fixupNode): - (JSC::DFG::FixupPhase::indexForChecks): - (JSC::DFG::FixupPhase::originForCheck): - (JSC::DFG::FixupPhase::speculateForBarrier): - (JSC::DFG::FixupPhase::insertCheck): - (JSC::DFG::FixupPhase::fixupChecksInBlock): - * dfg/DFGSpeculativeJIT.cpp: Add support for nuking. - (JSC::DFG::SpeculativeJIT::compileAllocatePropertyStorage): - (JSC::DFG::SpeculativeJIT::compileReallocatePropertyStorage): - * ftl/FTLLowerDFGToB3.cpp: Add support for nuking. - (JSC::FTL::DFG::LowerDFGToB3::allocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::reallocatePropertyStorage): - (JSC::FTL::DFG::LowerDFGToB3::mutatorFence): - (JSC::FTL::DFG::LowerDFGToB3::nukeStructureAndSetButterfly): - (JSC::FTL::DFG::LowerDFGToB3::setButterfly): Deleted. - * heap/CodeBlockSet.cpp: We need to be more careful about the CodeBlockSet workflow during GC, since we will allocate CodeBlocks in eden while collecting. - (JSC::CodeBlockSet::clearMarksForFullCollection): - (JSC::CodeBlockSet::deleteUnmarkedAndUnreferenced): - * heap/Heap.cpp: Added code to measure max pauses. Added a better collectContinuously mode. - (JSC::Heap::lastChanceToFinalize): Stop the collectContinuously thread. - (JSC::Heap::harvestWeakReferences): Inline SlotVisitor::harvestWeakReferences. - (JSC::Heap::finalizeUnconditionalFinalizers): Inline SlotVisitor::finalizeUnconditionalReferences. - (JSC::Heap::markToFixpoint): We need to do some MarkedSpace stuff before every conservative scan, rather than just at the start of marking, so we now call prepareForConservativeScan() before each conservative scan. Also call a less-parallel version of drainInParallel when the mutator is running. - (JSC::Heap::collectInThread): Inline Heap::prepareForAllocation(). - (JSC::Heap::stopIfNecessarySlow): We need to be more careful about ensuring that we run finalization before and after stopping. Also, we should sanitize stack when stopping the world. - (JSC::Heap::acquireAccessSlow): Add some optional debug prints. - (JSC::Heap::handleNeedFinalize): Assert that we are running this when the world is not stopped. - (JSC::Heap::finalize): Remove the old collectContinuously code. - (JSC::Heap::requestCollection): We don't need to sanitize stack here anymore. - (JSC::Heap::notifyIsSafeToCollect): Start the collectContinuously thread. It will request collection 1 KHz. - (JSC::Heap::prepareForAllocation): Deleted. - (JSC::Heap::preventCollection): Prevent any new concurrent GCs from being initiated. - (JSC::Heap::allowCollection): - (JSC::Heap::forEachSlotVisitor): Allows us to safely iterate slot visitors. - * heap/Heap.h: - * heap/HeapInlines.h: - (JSC::Heap::writeBarrier): If the 'to' cell is not NewWhite then it could be AnthraciteOrBlack. During a full collection, objects may be AnthraciteOrBlack from a previous GC. Turns out, we don't benefit from this optimization so we can just kill it. - * heap/HeapSnapshotBuilder.cpp: - (JSC::HeapSnapshotBuilder::buildSnapshot): This needs to use PreventCollectionScope to ensure snapshot soundness. - * heap/ListableHandler.h: - (JSC::ListableHandler::isOnList): Useful helper. - * heap/LockDuringMarking.h: - (JSC::lockDuringMarking): It's a locker that only locks while we're marking. - * heap/MarkedAllocator.cpp: - (JSC::MarkedAllocator::addBlock): Hold the bitvector lock while resizing. - * heap/MarkedBlock.cpp: Hold the bitvector lock while accessing the bitvectors while the mutator is running. - * heap/MarkedSpace.cpp: - (JSC::MarkedSpace::prepareForConservativeScan): We used to do this in prepareForMarking, but we need to do it before each conservative scan not just before marking. - (JSC::MarkedSpace::prepareForMarking): Remove the logic moved to prepareForConservativeScan. - * heap/MarkedSpace.h: - * heap/PreventCollectionScope.h: Added. - * heap/SlotVisitor.cpp: Refactored drainFromShared so that we can write a similar function called drainInParallelPassively. - (JSC::SlotVisitor::updateMutatorIsStopped): Update whether we can use "fast" scanning. - (JSC::SlotVisitor::mutatorIsStoppedIsUpToDate): - (JSC::SlotVisitor::didReachTermination): - (JSC::SlotVisitor::hasWork): - (JSC::SlotVisitor::drain): This now uses the rightToRun lock to allow the main GC thread to safepoint the workers. - (JSC::SlotVisitor::drainFromShared): - (JSC::SlotVisitor::drainInParallelPassively): This runs marking with one fewer threads than normal. It's useful for when we have resumed the mutator, since then the mutator has a better chance of getting on a core. - (JSC::SlotVisitor::addWeakReferenceHarvester): - (JSC::SlotVisitor::addUnconditionalFinalizer): - (JSC::SlotVisitor::harvestWeakReferences): Deleted. - (JSC::SlotVisitor::finalizeUnconditionalFinalizers): Deleted. - * heap/SlotVisitor.h: - * heap/SlotVisitorInlines.h: Outline stuff. - (JSC::SlotVisitor::addWeakReferenceHarvester): Deleted. - (JSC::SlotVisitor::addUnconditionalFinalizer): Deleted. - * runtime/InferredType.cpp: This needed thread safety. - (JSC::InferredType::visitChildren): This needs to keep its structure finalizer alive until it runs. - (JSC::InferredType::set): - (JSC::InferredType::InferredStructureFinalizer::finalizeUnconditionally): - * runtime/InferredType.h: - * runtime/InferredValue.cpp: This needed thread safety. - (JSC::InferredValue::visitChildren): - (JSC::InferredValue::ValueCleanup::finalizeUnconditionally): - * runtime/JSArray.cpp: - (JSC::JSArray::unshiftCountSlowCase): Update to use new butterfly API. - (JSC::JSArray::unshiftCountWithArrayStorage): Update to use new butterfly API. - * runtime/JSArrayBufferView.cpp: - (JSC::JSArrayBufferView::visitChildren): Thread safety. - * runtime/JSCell.h: - (JSC::JSCell::setStructureIDDirectly): This is used for nuking the structure. - (JSC::JSCell::InternalLocker::InternalLocker): Deleted. The cell is now the lock. - (JSC::JSCell::InternalLocker::~InternalLocker): Deleted. The cell is now the lock. - * runtime/JSCellInlines.h: - (JSC::JSCell::structure): Clean this up. - (JSC::JSCell::lock): The cell is now the lock. - (JSC::JSCell::tryLock): - (JSC::JSCell::unlock): - (JSC::JSCell::isLocked): - (JSC::JSCell::lockInternalLock): Deleted. - (JSC::JSCell::unlockInternalLock): Deleted. - * runtime/JSFunction.cpp: - (JSC::JSFunction::visitChildren): Thread safety. - * runtime/JSGenericTypedArrayViewInlines.h: - (JSC::JSGenericTypedArrayView::visitChildren): Thread safety. - (JSC::JSGenericTypedArrayView::slowDownAndWasteMemory): Thread safety. - * runtime/JSObject.cpp: - (JSC::JSObject::markAuxiliaryAndVisitOutOfLineProperties): Factor out this "easy" step of butterfly visiting. - (JSC::JSObject::visitButterfly): Make this achieve 100% precision about structure-butterfly relationships. This relies on the mutator "nuking" the structure prior to "locked" structure-butterfly transitions. - (JSC::JSObject::visitChildren): Use the new, nicer API. - (JSC::JSFinalObject::visitChildren): Use the new, nicer API. - (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists): Use the new butterfly API. - (JSC::JSObject::createInitialUndecided): Use the new butterfly API. - (JSC::JSObject::createInitialInt32): Use the new butterfly API. - (JSC::JSObject::createInitialDouble): Use the new butterfly API. - (JSC::JSObject::createInitialContiguous): Use the new butterfly API. - (JSC::JSObject::createArrayStorage): Use the new butterfly API. - (JSC::JSObject::convertUndecidedToContiguous): Use the new butterfly API. - (JSC::JSObject::convertUndecidedToArrayStorage): Use the new butterfly API. - (JSC::JSObject::convertInt32ToArrayStorage): Use the new butterfly API. - (JSC::JSObject::convertDoubleToContiguous): Use the new butterfly API. - (JSC::JSObject::convertDoubleToArrayStorage): Use the new butterfly API. - (JSC::JSObject::convertContiguousToArrayStorage): Use the new butterfly API. - (JSC::JSObject::increaseVectorLength): Use the new butterfly API. - (JSC::JSObject::shiftButterflyAfterFlattening): Use the new butterfly API. - * runtime/JSObject.h: - (JSC::JSObject::setButterfly): This now does all of the fences. Only use this when you are not also transitioning the structure or the structure's lastOffset. - (JSC::JSObject::nukeStructureAndSetButterfly): Use this when doing locked structure-butterfly transitions. - * runtime/JSObjectInlines.h: - (JSC::JSObject::putDirectWithoutTransition): Use the newly factored out API. - (JSC::JSObject::prepareToPutDirectWithoutTransition): Factor this out! - (JSC::JSObject::putDirectInternal): Use the newly factored out API. - * runtime/JSPropertyNameEnumerator.cpp: - (JSC::JSPropertyNameEnumerator::finishCreation): Locks! - (JSC::JSPropertyNameEnumerator::visitChildren): Locks! - * runtime/JSSegmentedVariableObject.cpp: - (JSC::JSSegmentedVariableObject::visitChildren): Locks! - * runtime/JSString.cpp: - (JSC::JSString::visitChildren): Thread safety. - * runtime/ModuleProgramExecutable.cpp: - (JSC::ModuleProgramExecutable::visitChildren): Thread safety. - * runtime/Options.cpp: For now we disable concurrent GC on not-X86_64. - (JSC::recomputeDependentOptions): - * runtime/Options.h: Change the default max GC parallelism to 8. I don't know why it was still 7. - * runtime/SamplingProfiler.cpp: - (JSC::SamplingProfiler::stackTracesAsJSON): This needs to defer GC before grabbing its lock. - * runtime/SparseArrayValueMap.cpp: This needed thread safety. - (JSC::SparseArrayValueMap::add): - (JSC::SparseArrayValueMap::remove): - (JSC::SparseArrayValueMap::visitChildren): - * runtime/SparseArrayValueMap.h: - * runtime/Structure.cpp: This had a race between addNewPropertyTransition and visitChildren. - (JSC::Structure::Structure): - (JSC::Structure::materializePropertyTable): - (JSC::Structure::addNewPropertyTransition): - (JSC::Structure::flattenDictionaryStructure): - (JSC::Structure::add): Help out with nuking support - the m_offset needs to play along. - (JSC::Structure::visitChildren): - * runtime/Structure.h: Make some useful things public - like the notion of a lastOffset. - * runtime/StructureChain.cpp: - (JSC::StructureChain::visitChildren): Thread safety! - * runtime/StructureChain.h: Thread safety! - * runtime/StructureIDTable.cpp: - (JSC::StructureIDTable::allocateID): Ensure that we don't get nuked IDs. - * runtime/StructureIDTable.h: Add the notion of a nuked ID! It's a bit that the runtime never sees except during specific shady actions like locked structure-butterfly transitions. "Nuking" tells the GC to steer clear and rescan once we fire the barrier. - (JSC::nukedStructureIDBit): - (JSC::nuke): - (JSC::isNuked): - (JSC::decontaminate): - * runtime/StructureInlines.h: - (JSC::Structure::hasIndexingHeader): Better API. - (JSC::Structure::add): - * runtime/VM.cpp: Better GC interaction. - (JSC::VM::ensureWatchdog): - (JSC::VM::deleteAllLinkedCode): - (JSC::VM::deleteAllCode): - * runtime/VM.h: - (JSC::VM::getStructure): Why wasn't this always an API! - * runtime/WebAssemblyExecutable.cpp: - (JSC::WebAssemblyExecutable::visitChildren): Thread safety. - -2016-12-08 Filip Pizlo - - Enable SharedArrayBuffer, remove the flag - https://bugs.webkit.org/show_bug.cgi?id=165614 - - Rubber stamped by Geoffrey Garen. - - * runtime/JSGlobalObject.cpp: - (JSC::JSGlobalObject::init): - * runtime/RuntimeFlags.h: - -2016-12-08 JF Bastien - - WebAssembly JS API: wire up Instance imports - https://bugs.webkit.org/show_bug.cgi?id=165118 - - Reviewed by Saam Barati. - - Change a bunch of the WebAssembly object model, and pipe the - necessary changes to be able to call JS imports from - WebAssembly. This will make it easier to call_indirect, and - unblock many other missing features. - - As a follow-up I need to teach JSC::linkFor to live without a - CodeBlock: wasm doesn't have one and the IC patching is sad. We'll - switch on the callee (or its type?) and then use that as the owner - (because the callee is alive if the instance is alive, ditto - module, and module owns the CallLinkInfo). - - * CMakeLists.txt: - * JavaScriptCore.xcodeproj/project.pbxproj: - * interpreter/CallFrame.h: - (JSC::ExecState::callee): give access to the callee as a JSCell - * jit/RegisterSet.cpp: dead code from previous WebAssembly implementation - * jsc.cpp: - (callWasmFunction): - (functionTestWasmModuleFunctions): - * runtime/JSCellInlines.h: - (JSC::ExecState::vm): check callee instead of jsCallee: wasm only has a JSCell and not a JSObject + * runtime/ExceptionScope.cpp: + (JSC::ExceptionScope::unexpectedExceptionMessage): * runtime/VM.cpp: - (JSC::VM::VM): store the "top" WebAssembly.Instance on entry to WebAssembly (and restore the previous one on exit) - * runtime/VM.h: - * testWasm.cpp: - (runWasmTests): - * wasm/JSWebAssembly.h: - * wasm/WasmB3IRGenerator.cpp: - (JSC::Wasm::B3IRGenerator::B3IRGenerator): pass unlinked calls around to shorten their lifetime: they're ony needed until the Plan is done - (JSC::Wasm::B3IRGenerator::addCall): - (JSC::Wasm::createJSToWasmWrapper): - (JSC::Wasm::parseAndCompile): also pass in the function index space, so that imports can be signature-checked along with internal functions - * wasm/WasmB3IRGenerator.h: - * wasm/WasmBinding.cpp: Added. - (JSC::Wasm::importStubGenerator): stubs from wasm to JS - * wasm/WasmBinding.h: Copied from Source/JavaScriptCore/wasm/WasmValidate.h. - * wasm/WasmCallingConvention.h: - (JSC::Wasm::CallingConvention::setupFrameInPrologue): - * wasm/WasmFormat.h: fix the object model - (JSC::Wasm::CallableFunction::CallableFunction): - * wasm/WasmFunctionParser.h: simplify some of the failure condition checks - (JSC::Wasm::FunctionParser::FunctionParser): need function index space, not just internal functions - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/WasmModuleParser.cpp: early-create some of the structures which will be needed later - (JSC::Wasm::ModuleParser::parseImport): - (JSC::Wasm::ModuleParser::parseFunction): - (JSC::Wasm::ModuleParser::parseMemory): - (JSC::Wasm::ModuleParser::parseExport): - (JSC::Wasm::ModuleParser::parseCode): - * wasm/WasmModuleParser.h: - (JSC::Wasm::ModuleParser::functionIndexSpace): - (JSC::Wasm::ModuleParser::functionLocations): - * wasm/WasmParser.h: - (JSC::Wasm::Parser::consumeUTF8String): - * wasm/WasmPlan.cpp: pass around the wasm objects at the right time, reducing their lifetime and making it easier to pass them around when needed - (JSC::Wasm::Plan::run): - (JSC::Wasm::Plan::initializeCallees): - * wasm/WasmPlan.h: - (JSC::Wasm::Plan::exports): - (JSC::Wasm::Plan::internalFunctionCount): - (JSC::Wasm::Plan::jsToWasmEntryPointForFunction): - (JSC::Wasm::Plan::takeModuleInformation): - (JSC::Wasm::Plan::takeCallLinkInfos): - (JSC::Wasm::Plan::takeWasmToJSStubs): - (JSC::Wasm::Plan::takeFunctionIndexSpace): - * wasm/WasmValidate.cpp: check function index space instead of only internal functions - (JSC::Wasm::Validate::addCall): - (JSC::Wasm::validateFunction): - * wasm/WasmValidate.h: - * wasm/js/JSWebAssemblyCallee.cpp: - (JSC::JSWebAssemblyCallee::finishCreation): - * wasm/js/JSWebAssemblyCallee.h: - (JSC::JSWebAssemblyCallee::create): - (JSC::JSWebAssemblyCallee::jsToWasmEntryPoint): - * wasm/js/JSWebAssemblyInstance.cpp: - (JSC::JSWebAssemblyInstance::create): - (JSC::JSWebAssemblyInstance::JSWebAssemblyInstance): - (JSC::JSWebAssemblyInstance::visitChildren): - * wasm/js/JSWebAssemblyInstance.h: hold the import functions off the end of the Instance - (JSC::JSWebAssemblyInstance::importFunction): - (JSC::JSWebAssemblyInstance::importFunctions): - (JSC::JSWebAssemblyInstance::setImportFunction): - (JSC::JSWebAssemblyInstance::offsetOfImportFunctions): - (JSC::JSWebAssemblyInstance::offsetOfImportFunction): - (JSC::JSWebAssemblyInstance::allocationSize): - * wasm/js/JSWebAssemblyModule.cpp: - (JSC::JSWebAssemblyModule::create): - (JSC::JSWebAssemblyModule::JSWebAssemblyModule): - (JSC::JSWebAssemblyModule::visitChildren): - * wasm/js/JSWebAssemblyModule.h: hold the link call info, the import function stubs, and the function index space - (JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace): - (JSC::JSWebAssemblyModule::importCount): - (JSC::JSWebAssemblyModule::calleeFromFunctionIndexSpace): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): set top Instance on VM - * wasm/js/WebAssemblyFunction.h: - (JSC::WebAssemblyFunction::instance): - * wasm/js/WebAssemblyInstanceConstructor.cpp: - (JSC::constructJSWebAssemblyInstance): handle function imports - * wasm/js/WebAssemblyModuleConstructor.cpp: - (JSC::constructJSWebAssemblyModule): generate the stubs for import functions - * wasm/js/WebAssemblyModuleRecord.cpp: - (JSC::WebAssemblyModuleRecord::link): - * wasm/js/WebAssemblyToJSCallee.cpp: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.cpp. - (JSC::WebAssemblyToJSCallee::create): dummy JSCell singleton which lives on the VM, and is put as the callee in the import stub's frame to identified it when unwinding - (JSC::WebAssemblyToJSCallee::createStructure): - (JSC::WebAssemblyToJSCallee::WebAssemblyToJSCallee): - (JSC::WebAssemblyToJSCallee::finishCreation): - (JSC::WebAssemblyToJSCallee::destroy): - * wasm/js/WebAssemblyToJSCallee.h: Copied from Source/JavaScriptCore/wasm/WasmB3IRGenerator.h. + (JSC::VM::throwException): -2016-12-08 Mark Lam +2017-07-14 Yusuke Suzuki - Enable JSC restricted options by default in the jsc shell. - https://bugs.webkit.org/show_bug.cgi?id=165615 - - Reviewed by Keith Miller. - - The jsc shell is only used for debugging and development testing. We should - allow it to use restricted options like JSC_useDollarVM even for release builds. - - * jsc.cpp: - (jscmain): - * runtime/Options.cpp: - (JSC::Options::enableRestrictedOptions): - (JSC::Options::isAvailable): - (JSC::allowRestrictedOptions): Deleted. - * runtime/Options.h: - -2016-12-08 Chris Dumez - - Unreviewed, rolling out r209489. - - Likely caused large regressions on JetStream, Sunspider and - Speedometer - - Reverted changeset: - - "Add system trace points for JavaScript VM entry/exit" - https://bugs.webkit.org/show_bug.cgi?id=165550 - http://trac.webkit.org/changeset/209489 - -2016-12-08 Keith Miller - - Move LEB tests to API tests - https://bugs.webkit.org/show_bug.cgi?id=165586 + [JSC] Use WTFMove to prune liveness in DFGAvailabilityMap + https://bugs.webkit.org/show_bug.cgi?id=174423 Reviewed by Saam Barati. - Delete old stuff. + * dfg/DFGAvailabilityMap.cpp: + (JSC::DFG::AvailabilityMap::pruneHeap): + (JSC::DFG::AvailabilityMap::pruneByLiveness): - * testWasm.cpp: - (printUsageStatement): - (CommandLine::parseArguments): - (main): - (runLEBTests): Deleted. +2017-07-13 Michael Catanzaro -2016-12-07 JF Bastien + Fix compiler warnings when building with GCC 7 + https://bugs.webkit.org/show_bug.cgi?id=174463 - Cleanup WebAssembly's RETURN_IF_EXCEPTION - https://bugs.webkit.org/show_bug.cgi?id=165595 + Reviewed by Darin Adler. - Reviewed by Filip Pizlo. + * disassembler/udis86/udis86_decode.c: + (decode_operand): - * wasm/js/WebAssemblyCompileErrorConstructor.cpp: - (JSC::constructJSWebAssemblyCompileError): - * wasm/js/WebAssemblyFunction.cpp: - (JSC::callWebAssemblyFunction): - * wasm/js/WebAssemblyRuntimeErrorConstructor.cpp: - (JSC::constructJSWebAssemblyRuntimeError): +2017-07-13 Michael Catanzaro -2016-12-07 Geoffrey Garen - - Renamed SourceCode members to match their accessor names - https://bugs.webkit.org/show_bug.cgi?id=165573 - - Reviewed by Keith Miller. - - startChar => startOffset - endChar => endOffset - - * parser/UnlinkedSourceCode.h: - (JSC::UnlinkedSourceCode::UnlinkedSourceCode): - (JSC::UnlinkedSourceCode::view): - (JSC::UnlinkedSourceCode::startOffset): - (JSC::UnlinkedSourceCode::endOffset): - (JSC::UnlinkedSourceCode::length): - -2016-12-07 Keith Miller - - Add more missing trivial wasm ops. - https://bugs.webkit.org/show_bug.cgi?id=165564 - - Reviewed by Geoffrey Garen. - - This patch adds the nop, drop, and tee_local opcodes. - It also fixes an issue where we were not generating - the proper enums for the grow_memory and current_memory - opcodes. - - * wasm/WasmFunctionParser.h: - (JSC::Wasm::FunctionParser::parseExpression): - * wasm/generateWasmOpsHeader.py: - -2016-12-07 Geoffrey Garen - - Renamed source => parentSource - https://bugs.webkit.org/show_bug.cgi?id=165570 - - Reviewed by Keith Miller. - - For less confuse. - - * bytecode/UnlinkedFunctionExecutable.cpp: - (JSC::UnlinkedFunctionExecutable::UnlinkedFunctionExecutable): - -2016-12-07 Yusuke Suzuki - - [JSC] Drop translate phase in module loader - https://bugs.webkit.org/show_bug.cgi?id=164861 + Incorrect assertion in JSC::CallLinkInfo::callTypeFor + https://bugs.webkit.org/show_bug.cgi?id=174467 Reviewed by Saam Barati. - Originally, this "translate" phase was introduced to the module loader. - However, recent rework discussion[1] starts dropping this phase. - And this "translate" phase is meaningless in the browser side module loader - since this phase originally mimics the node.js's translation hook (like, - transpiling CoffeeScript source to JavaScript). + * bytecode/CallLinkInfo.cpp: + (JSC::CallLinkInfo::callTypeFor): - This "translate" phase is not necessary for the exposed HTML5 -