Title: [213049] releases/WebKitGTK/webkit-2.16
Revision
213049
Author
[email protected]
Date
2017-02-27 05:44:03 -0800 (Mon, 27 Feb 2017)

Log Message

Merge r212818 - JSModuleNamespace object should have IC
https://bugs.webkit.org/show_bug.cgi?id=160590

Reviewed by Saam Barati.

JSTests:

* modules/module-assert-access-binding.js: Added.
* modules/module-assert-access-namespace.js: Added.
* modules/namespace-empty.js: Added.
(from.string_appeared_here.access):
(i.shouldThrow):
* stress/module-namespace-access-change.js: Added.
(shouldBe):
(access):
(import.string_appeared_here.then):
* stress/module-namespace-access-non-constant.js: Added.
(shouldBe):
(import.string_appeared_here.then):
* stress/module-namespace-access-poly.js: Added.
(shouldBe):
(access):
(import.string_appeared_here.then):
* stress/module-namespace-access-transitive-exports.js: Added.
(shouldBe):
(import.string_appeared_here.then):
* stress/module-namespace-access.js: Added.
(shouldBe):
(import.string_appeared_here.then):
* stress/resources/module-namespace-access-transitive-exports-2.js: Added.
(export.cocoa):
(export.change):
* stress/resources/module-namespace-access-transitive-exports.js: Added.
* stress/resources/module-namespace-access.js: Added.
(export.cocoa):
(export.change):

Source/_javascript_Core:

This patch optimizes accesses to module namespace objects.

1. Cache the resolutions for module namespace objects.

    When constructing the module namespace object, we already resolves all the exports.
    The module namespace object caches this result and leverage it in the later access in
    getOwnPropertySlot. This avoids resolving bindings through resolveExport.

2. Introduce ModuleNamespaceLoad IC.

    This patch adds new IC for module namespace objects. The mechanism is simple, getOwnPropertySlot
    tells us about module namespace object resolution. The IC first checks whether the given object
    is an expected module namespace object. If this check succeeds, we load the value from the module
    environment.

3. Introduce DFG/FTL optimization.

    After exploiting module namespace object accesses in (2), DFG can recognize this in ByteCodeParser.
    DFG will convert it to CheckCell with the namespace object and GetClosureVar from the cached environment.
    At that time, we have a chance to fold it to the constant.

This optimization improves the performance of accessing to module namespace objects.

Before
    $ time ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m module-assert-access-namespace.js
    ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m   0.43s user 0.03s system 101% cpu 0.451 total
    $ time ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m module-assert-access-binding.js
    ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m   0.08s user 0.02s system 103% cpu 0.104 total

After
    $ time ../../WebKitBuild/module-ic/Release/bin/jsc -m module-assert-access-namespace.js
    ../../WebKitBuild/module-ic/Release/bin/jsc -m   0.11s user 0.01s system 106% cpu 0.109 total
    $ time ../../WebKitBuild/module-ic/Release/bin/jsc -m module-assert-access-binding.js
    ../../WebKitBuild/module-ic/Release/bin/jsc -m module-assert-access-binding.j  0.08s user 0.02s system 102% cpu 0.105 total

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* bytecode/AccessCase.cpp:
(JSC::AccessCase::create):
(JSC::AccessCase::guardedByStructureCheck):
(JSC::AccessCase::canReplace):
(JSC::AccessCase::visitWeak):
(JSC::AccessCase::generateWithGuard):
(JSC::AccessCase::generateImpl):
* bytecode/AccessCase.h:
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::GetByIdStatus):
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::GetByIdStatus::makesCalls):
(JSC::GetByIdStatus::dump):
* bytecode/GetByIdStatus.h:
(JSC::GetByIdStatus::isModuleNamespace):
(JSC::GetByIdStatus::takesSlowPath):
(JSC::GetByIdStatus::moduleNamespaceObject):
(JSC::GetByIdStatus::moduleEnvironment):
(JSC::GetByIdStatus::scopeOffset):
* bytecode/ModuleNamespaceAccessCase.cpp: Added.
(JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
(JSC::ModuleNamespaceAccessCase::create):
(JSC::ModuleNamespaceAccessCase::~ModuleNamespaceAccessCase):
(JSC::ModuleNamespaceAccessCase::clone):
(JSC::ModuleNamespaceAccessCase::emit):
* bytecode/ModuleNamespaceAccessCase.h: Added.
(JSC::ModuleNamespaceAccessCase::moduleNamespaceObject):
(JSC::ModuleNamespaceAccessCase::moduleEnvironment):
(JSC::ModuleNamespaceAccessCase::scopeOffset):
* bytecode/PolymorphicAccess.cpp:
(WTF::printInternal):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleModuleNamespaceLoad):
(JSC::DFG::ByteCodeParser::handleGetById):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::loadValue):
* jit/Repatch.cpp:
(JSC::tryCacheGetByID):
* runtime/AbstractModuleRecord.cpp:
(JSC::AbstractModuleRecord::getModuleNamespace):
* runtime/JSModuleNamespaceObject.cpp:
(JSC::JSModuleNamespaceObject::finishCreation):
(JSC::JSModuleNamespaceObject::visitChildren):
(JSC::getValue):
(JSC::JSModuleNamespaceObject::getOwnPropertySlot):
(JSC::JSModuleNamespaceObject::getOwnPropertyNames):
* runtime/JSModuleNamespaceObject.h:
(JSC::isJSModuleNamespaceObject):
(JSC::JSModuleNamespaceObject::create): Deleted.
(JSC::JSModuleNamespaceObject::createStructure): Deleted.
(JSC::JSModuleNamespaceObject::moduleRecord): Deleted.
* runtime/JSModuleRecord.h:
(JSC::JSModuleRecord::moduleEnvironment): Deleted.
* runtime/PropertySlot.h:
(JSC::PropertySlot::PropertySlot):
(JSC::PropertySlot::domJIT):
(JSC::PropertySlot::moduleNamespaceSlot):
(JSC::PropertySlot::setValueModuleNamespace):
(JSC::PropertySlot::setCacheableCustom):

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/JSTests/ChangeLog	2017-02-27 13:44:03 UTC (rev 213049)
@@ -1,3 +1,40 @@
+2017-02-22  Yusuke Suzuki  <[email protected]>
+
+        JSModuleNamespace object should have IC
+        https://bugs.webkit.org/show_bug.cgi?id=160590
+
+        Reviewed by Saam Barati.
+
+        * modules/module-assert-access-binding.js: Added.
+        * modules/module-assert-access-namespace.js: Added.
+        * modules/namespace-empty.js: Added.
+        (from.string_appeared_here.access):
+        (i.shouldThrow):
+        * stress/module-namespace-access-change.js: Added.
+        (shouldBe):
+        (access):
+        (import.string_appeared_here.then):
+        * stress/module-namespace-access-non-constant.js: Added.
+        (shouldBe):
+        (import.string_appeared_here.then):
+        * stress/module-namespace-access-poly.js: Added.
+        (shouldBe):
+        (access):
+        (import.string_appeared_here.then):
+        * stress/module-namespace-access-transitive-exports.js: Added.
+        (shouldBe):
+        (import.string_appeared_here.then):
+        * stress/module-namespace-access.js: Added.
+        (shouldBe):
+        (import.string_appeared_here.then):
+        * stress/resources/module-namespace-access-transitive-exports-2.js: Added.
+        (export.cocoa):
+        (export.change):
+        * stress/resources/module-namespace-access-transitive-exports.js: Added.
+        * stress/resources/module-namespace-access.js: Added.
+        (export.cocoa):
+        (export.change):
+
 2017-02-20  Filip Pizlo  <[email protected]>
 
         The collector thread should only start when the mutator doesn't have heap access

Added: releases/WebKitGTK/webkit-2.16/JSTests/modules/module-assert-access-binding.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/modules/module-assert-access-binding.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/modules/module-assert-access-binding.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,10 @@
+import {shouldBe} from "./resources/assert.js";
+
+let array = [];
+for (let i = 0; i < 4000000; i++) {
+    array.push(i);
+}
+
+for (let i = 0; i < 4000000; i++) {
+    shouldBe(array[i], i);
+}

Added: releases/WebKitGTK/webkit-2.16/JSTests/modules/module-assert-access-namespace.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/modules/module-assert-access-namespace.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/modules/module-assert-access-namespace.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,10 @@
+import * as assert from "./resources/assert.js";
+
+let array = [];
+for (let i = 0; i < 4000000; i++) {
+    array.push(i);
+}
+
+for (let i = 0; i < 4000000; i++) {
+    assert.shouldBe(array[i], i);
+}

Added: releases/WebKitGTK/webkit-2.16/JSTests/modules/namespace-empty.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/modules/namespace-empty.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/modules/namespace-empty.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,17 @@
+import * as ns from "./namespace-empty.js"
+import {shouldThrow} from "./resources/assert.js"
+
+function access(ns)
+{
+    return ns.test;
+}
+noInline(access);
+
+for (var i = 0; i < 1e3; ++i) {
+    shouldThrow(() => {
+        access(ns);
+    }, `ReferenceError: Cannot access uninitialized variable.`);
+}
+
+
+export let test = 42;

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-change.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-change.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-change.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,19 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function access(namespace)
+{
+    return namespace.test;
+}
+noInline(access);
+
+import("./resources/module-namespace-access.js").then((ns) => {
+    for (var i = 0; i < 1e4; ++i)
+        shouldBe(access(ns), 42)
+    ns.change();
+    for (var i = 0; i < 1e4; ++i)
+        shouldBe(access(ns), 55)
+});
+drainMicrotasks();

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-non-constant.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-non-constant.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-non-constant.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,13 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+import("./resources/module-namespace-access.js").then((ns) => {
+    ns.change();
+    for (var i = 0; i < 1e6; ++i) {
+        shouldBe(ns.test, 55);
+        shouldBe(ns.cocoa(), 55);
+    }
+});
+drainMicrotasks();

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-poly.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-poly.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-poly.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,24 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function access(ns)
+{
+    return ns.test;
+}
+noInline(access);
+
+import("./resources/module-namespace-access.js").then((ns) => {
+    for (var i = 0; i < 1e4; ++i) {
+        shouldBe(access(ns), 42);
+    }
+    let nonNS = { test: 50 };
+    let nonNS2 = { ok: 22, test: 52 };
+    for (var i = 0; i < 1e4; ++i) {
+        shouldBe(access(ns), 42);
+        shouldBe(access(nonNS), 50);
+        shouldBe(access(nonNS2), 52);
+    }
+});
+drainMicrotasks();

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-transitive-exports.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-transitive-exports.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access-transitive-exports.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,12 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+import("./resources/module-namespace-access-transitive-exports.js").then((ns) => {
+    for (var i = 0; i < 1e6; ++i) {
+        shouldBe(ns.test, 42);
+        shouldBe(ns.cocoa(), 42);
+    }
+});
+drainMicrotasks();

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/module-namespace-access.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,12 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+import("./resources/module-namespace-access.js").then((ns) => {
+    for (var i = 0; i < 1e6; ++i) {
+        shouldBe(ns.test, 42);
+        shouldBe(ns.cocoa(), 42);
+    }
+});
+drainMicrotasks();

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access-transitive-exports-2.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access-transitive-exports-2.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access-transitive-exports-2.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,10 @@
+export let test = 42;
+export function cocoa()
+{
+    return test;
+}
+
+export function change()
+{
+    test = 55;
+}

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access-transitive-exports.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access-transitive-exports.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access-transitive-exports.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1 @@
+export * from "./module-namespace-access-transitive-exports-2.js"

Added: releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access.js (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/JSTests/stress/resources/module-namespace-access.js	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,10 @@
+export let test = 42;
+export function cocoa()
+{
+    return test;
+}
+
+export function change()
+{
+    test = 55;
+}

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/CMakeLists.txt (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/CMakeLists.txt	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/CMakeLists.txt	2017-02-27 13:44:03 UTC (rev 213049)
@@ -228,6 +228,7 @@
     bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp
     bytecode/LazyOperandValueProfile.cpp
     bytecode/MethodOfGettingAValueProfile.cpp
+    bytecode/ModuleNamespaceAccessCase.cpp
     bytecode/ModuleProgramCodeBlock.cpp
     bytecode/ObjectPropertyCondition.cpp
     bytecode/ObjectPropertyConditionSet.cpp

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/ChangeLog	2017-02-27 13:44:03 UTC (rev 213049)
@@ -1,3 +1,107 @@
+2017-02-22  Yusuke Suzuki  <[email protected]>
+
+        JSModuleNamespace object should have IC
+        https://bugs.webkit.org/show_bug.cgi?id=160590
+
+        Reviewed by Saam Barati.
+
+        This patch optimizes accesses to module namespace objects.
+
+        1. Cache the resolutions for module namespace objects.
+
+            When constructing the module namespace object, we already resolves all the exports.
+            The module namespace object caches this result and leverage it in the later access in
+            getOwnPropertySlot. This avoids resolving bindings through resolveExport.
+
+        2. Introduce ModuleNamespaceLoad IC.
+
+            This patch adds new IC for module namespace objects. The mechanism is simple, getOwnPropertySlot
+            tells us about module namespace object resolution. The IC first checks whether the given object
+            is an expected module namespace object. If this check succeeds, we load the value from the module
+            environment.
+
+        3. Introduce DFG/FTL optimization.
+
+            After exploiting module namespace object accesses in (2), DFG can recognize this in ByteCodeParser.
+            DFG will convert it to CheckCell with the namespace object and GetClosureVar from the cached environment.
+            At that time, we have a chance to fold it to the constant.
+
+        This optimization improves the performance of accessing to module namespace objects.
+
+        Before
+            $ time ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m module-assert-access-namespace.js
+            ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m   0.43s user 0.03s system 101% cpu 0.451 total
+            $ time ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m module-assert-access-binding.js
+            ../../WebKitBuild/module-ic-tot/Release/bin/jsc -m   0.08s user 0.02s system 103% cpu 0.104 total
+
+        After
+            $ time ../../WebKitBuild/module-ic/Release/bin/jsc -m module-assert-access-namespace.js
+            ../../WebKitBuild/module-ic/Release/bin/jsc -m   0.11s user 0.01s system 106% cpu 0.109 total
+            $ time ../../WebKitBuild/module-ic/Release/bin/jsc -m module-assert-access-binding.js
+            ../../WebKitBuild/module-ic/Release/bin/jsc -m module-assert-access-binding.j  0.08s user 0.02s system 102% cpu 0.105 total
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::create):
+        (JSC::AccessCase::guardedByStructureCheck):
+        (JSC::AccessCase::canReplace):
+        (JSC::AccessCase::visitWeak):
+        (JSC::AccessCase::generateWithGuard):
+        (JSC::AccessCase::generateImpl):
+        * bytecode/AccessCase.h:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::GetByIdStatus):
+        (JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
+        (JSC::GetByIdStatus::makesCalls):
+        (JSC::GetByIdStatus::dump):
+        * bytecode/GetByIdStatus.h:
+        (JSC::GetByIdStatus::isModuleNamespace):
+        (JSC::GetByIdStatus::takesSlowPath):
+        (JSC::GetByIdStatus::moduleNamespaceObject):
+        (JSC::GetByIdStatus::moduleEnvironment):
+        (JSC::GetByIdStatus::scopeOffset):
+        * bytecode/ModuleNamespaceAccessCase.cpp: Added.
+        (JSC::ModuleNamespaceAccessCase::ModuleNamespaceAccessCase):
+        (JSC::ModuleNamespaceAccessCase::create):
+        (JSC::ModuleNamespaceAccessCase::~ModuleNamespaceAccessCase):
+        (JSC::ModuleNamespaceAccessCase::clone):
+        (JSC::ModuleNamespaceAccessCase::emit):
+        * bytecode/ModuleNamespaceAccessCase.h: Added.
+        (JSC::ModuleNamespaceAccessCase::moduleNamespaceObject):
+        (JSC::ModuleNamespaceAccessCase::moduleEnvironment):
+        (JSC::ModuleNamespaceAccessCase::scopeOffset):
+        * bytecode/PolymorphicAccess.cpp:
+        (WTF::printInternal):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::handleModuleNamespaceLoad):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::loadValue):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        * runtime/AbstractModuleRecord.cpp:
+        (JSC::AbstractModuleRecord::getModuleNamespace):
+        * runtime/JSModuleNamespaceObject.cpp:
+        (JSC::JSModuleNamespaceObject::finishCreation):
+        (JSC::JSModuleNamespaceObject::visitChildren):
+        (JSC::getValue):
+        (JSC::JSModuleNamespaceObject::getOwnPropertySlot):
+        (JSC::JSModuleNamespaceObject::getOwnPropertyNames):
+        * runtime/JSModuleNamespaceObject.h:
+        (JSC::isJSModuleNamespaceObject):
+        (JSC::JSModuleNamespaceObject::create): Deleted.
+        (JSC::JSModuleNamespaceObject::createStructure): Deleted.
+        (JSC::JSModuleNamespaceObject::moduleRecord): Deleted.
+        * runtime/JSModuleRecord.h:
+        (JSC::JSModuleRecord::moduleEnvironment): Deleted.
+        * runtime/PropertySlot.h:
+        (JSC::PropertySlot::PropertySlot):
+        (JSC::PropertySlot::domJIT):
+        (JSC::PropertySlot::moduleNamespaceSlot):
+        (JSC::PropertySlot::setValueModuleNamespace):
+        (JSC::PropertySlot::setCacheableCustom):
+
 2017-02-21  Mark Lam  <[email protected]>
 
         Add more missing exception checks detected by running marathon.js.

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2017-02-27 13:44:03 UTC (rev 213049)
@@ -2410,6 +2410,8 @@
 		FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
 		FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		321D9E4CFB67423A97F191A7 /* ModuleNamespaceAccessCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 20ECB15EFC524624BC2F02D5 /* ModuleNamespaceAccessCase.cpp */; };
+		9F63434577274FAFB9336C38 /* ModuleNamespaceAccessCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CE978E385A8498199052153 /* ModuleNamespaceAccessCase.h */; };
 /* End PBXBuildFile section */
 
 /* Begin PBXContainerItemProxy section */
@@ -4976,6 +4978,8 @@
 		FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = "<group>"; };
 		FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = "<group>"; };
 		FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = "<group>"; };
+		20ECB15EFC524624BC2F02D5 /* ModuleNamespaceAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModuleNamespaceAccessCase.cpp; path = ModuleNamespaceAccessCase.cpp; sourceTree = "<group>"; };
+		4CE978E385A8498199052153 /* ModuleNamespaceAccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ModuleNamespaceAccessCase.h; path = ModuleNamespaceAccessCase.h; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -7514,6 +7518,8 @@
 				0F426A461460CBAB00131F8F /* VirtualRegister.h */,
 				0F919D2215853CDE004A4E7D /* Watchpoint.cpp */,
 				0F919D2315853CDE004A4E7D /* Watchpoint.h */,
+				20ECB15EFC524624BC2F02D5 /* ModuleNamespaceAccessCase.cpp */,
+				4CE978E385A8498199052153 /* ModuleNamespaceAccessCase.h */,
 			);
 			path = bytecode;
 			sourceTree = "<group>";
@@ -9267,6 +9273,7 @@
 				86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
 				86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
 				86704B4312DB8A8100A9FE7B /* YarrSyntaxChecker.h in Headers */,
+				9F63434577274FAFB9336C38 /* ModuleNamespaceAccessCase.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -10670,6 +10677,7 @@
 				86704B8612DBA33700A9FE7B /* YarrJIT.cpp in Sources */,
 				86704B8912DBA33700A9FE7B /* YarrPattern.cpp in Sources */,
 				86704B4212DB8A8100A9FE7B /* YarrSyntaxChecker.cpp in Sources */,
+				321D9E4CFB67423A97F191A7 /* ModuleNamespaceAccessCase.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/AccessCase.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/AccessCase.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/AccessCase.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -37,7 +37,10 @@
 #include "HeapInlines.h"
 #include "IntrinsicGetterAccessCase.h"
 #include "JSCJSValueInlines.h"
+#include "JSModuleEnvironment.h"
+#include "JSModuleNamespaceObject.h"
 #include "LinkBuffer.h"
+#include "ModuleNamespaceAccessCase.h"
 #include "PolymorphicAccess.h"
 #include "ScopedArguments.h"
 #include "ScratchRegisterAllocator.h"
@@ -65,6 +68,7 @@
     case StringLength:
     case DirectArgumentsLength:
     case ScopedArgumentsLength:
+    case ModuleNamespaceLoad:
     case Replace:
         break;
     default:
@@ -148,6 +152,7 @@
     case StringLength:
     case DirectArgumentsLength:
     case ScopedArgumentsLength:
+    case ModuleNamespaceLoad:
         return false;
     default:
         return true;
@@ -193,6 +198,13 @@
     case DirectArgumentsLength:
     case ScopedArgumentsLength:
         return other.type() == type();
+    case ModuleNamespaceLoad: {
+        if (other.type() != type())
+            return false;
+        auto& thisCase = this->as<ModuleNamespaceAccessCase>();
+        auto& otherCase = this->as<ModuleNamespaceAccessCase>();
+        return thisCase.moduleNamespaceObject() == otherCase.moduleNamespaceObject();
+    }
     default:
         if (!guardedByStructureCheck() || !other.guardedByStructureCheck())
             return false;
@@ -239,6 +251,12 @@
         auto& intrinsic = this->as<IntrinsicGetterAccessCase>();
         if (intrinsic.intrinsicFunction() && !Heap::isMarked(intrinsic.intrinsicFunction()))
             return false;
+    } else if (type() == ModuleNamespaceLoad) {
+        auto& accessCase = this->as<ModuleNamespaceAccessCase>();
+        if (accessCase.moduleNamespaceObject() && !Heap::isMarked(accessCase.moduleNamespaceObject()))
+            return false;
+        if (accessCase.moduleEnvironment() && !Heap::isMarked(accessCase.moduleEnvironment()))
+            return false;
     }
 
     return true;
@@ -344,6 +362,11 @@
         return;
     }
 
+    case ModuleNamespaceLoad: {
+        this->as<ModuleNamespaceAccessCase>().emit(state, fallThrough);
+        return;
+    }
+
     default: {
         if (viaProxy()) {
             fallThrough.append(
@@ -991,6 +1014,7 @@
         
     case DirectArgumentsLength:
     case ScopedArgumentsLength:
+    case ModuleNamespaceLoad:
         // These need to be handled by generateWithGuard(), since the guard is part of the
         // algorithm. We can be sure that nobody will call generate() directly for these since they
         // are not guarded by structure checks.

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/AccessCase.h (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/AccessCase.h	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/AccessCase.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -95,7 +95,8 @@
         ArrayLength,
         StringLength,
         DirectArgumentsLength,
-        ScopedArgumentsLength
+        ScopedArgumentsLength,
+        ModuleNamespaceLoad,
     };
 
     enum State : uint8_t {

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/GetByIdStatus.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/GetByIdStatus.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/GetByIdStatus.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -34,6 +34,7 @@
 #include "JSScope.h"
 #include "LLIntData.h"
 #include "LowLevelInterpreter.h"
+#include "ModuleNamespaceAccessCase.h"
 #include "PolymorphicAccess.h"
 #include "StructureStubInfo.h"
 #include <wtf/ListDump.h>
@@ -147,6 +148,15 @@
 #endif // ENABLE(DFG_JIT)
 
 #if ENABLE(JIT)
+GetByIdStatus::GetByIdStatus(const ModuleNamespaceAccessCase& accessCase)
+    : m_state(ModuleNamespace)
+    , m_wasSeenInJIT(true)
+    , m_moduleNamespaceObject(accessCase.moduleNamespaceObject())
+    , m_moduleEnvironment(accessCase.moduleEnvironment())
+    , m_scopeOffset(accessCase.scopeOffset())
+{
+}
+
 GetByIdStatus GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback(
     const ConcurrentJSLocker& locker, CodeBlock* profiledBlock, StructureStubInfo* stubInfo, UniquedStringImpl* uid,
     CallLinkStatus::ExitSiteData callExitSiteData)
@@ -195,6 +205,16 @@
     }
         
     case CacheType::Stub: {
+        if (list->size() == 1) {
+            const AccessCase& access = list->at(0);
+            switch (access.type()) {
+            case AccessCase::ModuleNamespaceLoad:
+                return GetByIdStatus(access.as<ModuleNamespaceAccessCase>());
+            default:
+                break;
+            }
+        }
+
         for (unsigned listIndex = 0; listIndex < list->size(); ++listIndex) {
             const AccessCase& access = list->at(listIndex);
             if (access.viaProxy())
@@ -376,6 +396,7 @@
     case NoInformation:
     case TakesSlowPath:
     case Custom:
+    case ModuleNamespace:
         return false;
     case Simple:
         for (unsigned i = m_variants.size(); i--;) {
@@ -420,6 +441,9 @@
     case Custom:
         out.print("Custom");
         break;
+    case ModuleNamespace:
+        out.print("ModuleNamespace");
+        break;
     case TakesSlowPath:
         out.print("TakesSlowPath");
         break;

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/GetByIdStatus.h (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/GetByIdStatus.h	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/GetByIdStatus.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -30,10 +30,15 @@
 #include "ConcurrentJSLock.h"
 #include "ExitingJITType.h"
 #include "GetByIdVariant.h"
+#include "ScopeOffset.h"
 
 namespace JSC {
 
+class AccessCase;
 class CodeBlock;
+class JSModuleEnvironment;
+class JSModuleNamespaceObject;
+class ModuleNamespaceAccessCase;
 class StructureStubInfo;
 
 typedef HashMap<CodeOrigin, StructureStubInfo*, CodeOriginApproximateHash> StubInfoMap;
@@ -41,12 +46,19 @@
 class GetByIdStatus {
 public:
     enum State {
-        NoInformation,  // It's uncached so we have no information.
-        Simple,         // It's cached for a simple access to a known object property with
-                        // a possible structure chain and a possible specific value.
-        Custom,         // It's cached for a custom accessor with a possible structure chain.
-        TakesSlowPath,  // It's known to often take slow path.
-        MakesCalls      // It's known to take paths that make calls.
+        // It's uncached so we have no information.
+        NoInformation,
+        // It's cached for a simple access to a known object property with
+        // a possible structure chain and a possible specific value.
+        Simple,
+        // It's cached for a custom accessor with a possible structure chain.
+        Custom,
+        // It's cached for an access to a module namespace object's binding.
+        ModuleNamespace,
+        // It's known to often take slow path.
+        TakesSlowPath,
+        // It's known to take paths that make calls.
+        MakesCalls,
     };
 
     GetByIdStatus()
@@ -59,6 +71,7 @@
     {
         ASSERT(state == NoInformation || state == TakesSlowPath || state == MakesCalls);
     }
+
     
     GetByIdStatus(
         State state, bool wasSeenInJIT, const GetByIdVariant& variant = GetByIdVariant())
@@ -84,6 +97,7 @@
     bool operator!() const { return !isSet(); }
     bool isSimple() const { return m_state == Simple; }
     bool isCustom() const { return m_state == Custom; }
+    bool isModuleNamespace() const { return m_state == ModuleNamespace; }
 
     size_t numVariants() const { return m_variants.size(); }
     const Vector<GetByIdVariant, 1>& variants() const { return m_variants; }
@@ -90,7 +104,7 @@
     const GetByIdVariant& at(size_t index) const { return m_variants[index]; }
     const GetByIdVariant& operator[](size_t index) const { return at(index); }
 
-    bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls || m_state == Custom; }
+    bool takesSlowPath() const { return m_state == TakesSlowPath || m_state == MakesCalls || m_state == Custom || m_state == ModuleNamespace; }
     bool makesCalls() const;
     
     bool wasSeenInJIT() const { return m_wasSeenInJIT; }
@@ -97,6 +111,10 @@
     
     // Attempts to reduce the set of variants to fit the given structure set. This may be approximate.
     void filter(const StructureSet&);
+
+    JSModuleNamespaceObject* moduleNamespaceObject() const { return m_moduleNamespaceObject; }
+    JSModuleEnvironment* moduleEnvironment() const { return m_moduleEnvironment; }
+    ScopeOffset scopeOffset() const { return m_scopeOffset; }
     
     void dump(PrintStream&) const;
     
@@ -105,6 +123,7 @@
     static bool hasExitSite(const ConcurrentJSLocker&, CodeBlock*, unsigned bytecodeIndex);
 #endif
 #if ENABLE(JIT)
+    GetByIdStatus(const ModuleNamespaceAccessCase&);
     static GetByIdStatus computeForStubInfoWithoutExitSiteFeedback(
         const ConcurrentJSLocker&, CodeBlock* profiledBlock, StructureStubInfo*,
         UniquedStringImpl* uid, CallLinkStatus::ExitSiteData);
@@ -116,6 +135,9 @@
     State m_state;
     Vector<GetByIdVariant, 1> m_variants;
     bool m_wasSeenInJIT;
+    JSModuleNamespaceObject* m_moduleNamespaceObject { nullptr };
+    JSModuleEnvironment* m_moduleEnvironment { nullptr };
+    ScopeOffset m_scopeOffset { };
 };
 
 } // namespace JSC

Added: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/ModuleNamespaceAccessCase.cpp (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/ModuleNamespaceAccessCase.cpp	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/ModuleNamespaceAccessCase.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 Yusuke Suzuki <[email protected]>.
+ *
+ * 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 "ModuleNamespaceAccessCase.h"
+
+#if ENABLE(JIT)
+
+#include "CCallHelpers.h"
+#include "HeapInlines.h"
+#include "JSModuleEnvironment.h"
+#include "JSModuleNamespaceObject.h"
+#include "PolymorphicAccess.h"
+#include "StructureStubInfo.h"
+
+namespace JSC {
+
+ModuleNamespaceAccessCase::ModuleNamespaceAccessCase(VM& vm, JSCell* owner, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)
+    : Base(vm, owner, ModuleNamespaceLoad, invalidOffset, nullptr, ObjectPropertyConditionSet())
+    , m_scopeOffset(scopeOffset)
+{
+    m_moduleNamespaceObject.set(vm, owner, moduleNamespaceObject);
+    m_moduleEnvironment.set(vm, owner, moduleEnvironment);
+}
+
+std::unique_ptr<AccessCase> ModuleNamespaceAccessCase::create(VM& vm, JSCell* owner, JSModuleNamespaceObject* moduleNamespaceObject, JSModuleEnvironment* moduleEnvironment, ScopeOffset scopeOffset)
+{
+    return std::unique_ptr<AccessCase>(new ModuleNamespaceAccessCase(vm, owner, moduleNamespaceObject, moduleEnvironment, scopeOffset));
+}
+
+ModuleNamespaceAccessCase::~ModuleNamespaceAccessCase()
+{
+}
+
+std::unique_ptr<AccessCase> ModuleNamespaceAccessCase::clone() const
+{
+    std::unique_ptr<ModuleNamespaceAccessCase> result(new ModuleNamespaceAccessCase(*this));
+    result->resetState();
+    return WTFMove(result);
+}
+
+void ModuleNamespaceAccessCase::emit(AccessGenerationState& state, MacroAssembler::JumpList& fallThrough)
+{
+    CCallHelpers& jit = *state.jit;
+    JSValueRegs valueRegs = state.valueRegs;
+    GPRReg baseGPR = state.baseGPR;
+
+    fallThrough.append(
+        jit.branchPtr(
+            CCallHelpers::NotEqual,
+            baseGPR,
+            CCallHelpers::TrustedImmPtr(m_moduleNamespaceObject.get())));
+
+    jit.loadValue(&m_moduleEnvironment->variableAt(m_scopeOffset), valueRegs);
+    state.failAndIgnore.append(jit.branchIfEmpty(valueRegs));
+    state.succeed();
+}
+
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)

Added: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/ModuleNamespaceAccessCase.h (0 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/ModuleNamespaceAccessCase.h	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/ModuleNamespaceAccessCase.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 Yusuke Suzuki <[email protected]>.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#if ENABLE(JIT)
+
+#include "AccessCase.h"
+
+namespace JSC {
+
+class JSModuleEnvironment;
+class JSModuleNamespaceObject;
+
+class ModuleNamespaceAccessCase : public AccessCase {
+public:
+    using Base = AccessCase;
+    friend class AccessCase;
+
+    JSModuleNamespaceObject* moduleNamespaceObject() const { return m_moduleNamespaceObject.get(); }
+    JSModuleEnvironment* moduleEnvironment() const { return m_moduleEnvironment.get(); }
+    ScopeOffset scopeOffset() const { return m_scopeOffset; }
+
+    static std::unique_ptr<AccessCase> create(VM&, JSCell* owner, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);
+
+    std::unique_ptr<AccessCase> clone() const override;
+
+    void emit(AccessGenerationState&, MacroAssembler::JumpList& fallThrough);
+
+    ~ModuleNamespaceAccessCase();
+
+private:
+    ModuleNamespaceAccessCase(VM&, JSCell* owner, JSModuleNamespaceObject*, JSModuleEnvironment*, ScopeOffset);
+
+    WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject;
+    WriteBarrier<JSModuleEnvironment> m_moduleEnvironment;
+    ScopeOffset m_scopeOffset;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/bytecode/PolymorphicAccess.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -645,6 +645,9 @@
     case AccessCase::ScopedArgumentsLength:
         out.print("ScopedArgumentsLength");
         return;
+    case AccessCase::ModuleNamespaceLoad:
+        out.print("ModuleNamespaceLoad");
+        return;
     }
 
     RELEASE_ASSERT_NOT_REACHED();

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -46,6 +46,7 @@
 #include "Heap.h"
 #include "JSCInlines.h"
 #include "JSModuleEnvironment.h"
+#include "JSModuleNamespaceObject.h"
 #include "NumberConstructor.h"
 #include "ObjectConstructor.h"
 #include "PreciseJumpTargets.h"
@@ -223,6 +224,7 @@
     Node* handlePutByOffset(Node* base, unsigned identifier, PropertyOffset, const InferredType::Descriptor&, Node* value);
     Node* handleGetByOffset(SpeculatedType, Node* base, unsigned identifierNumber, PropertyOffset, const InferredType::Descriptor&, NodeType = GetByOffset);
     bool handleDOMJITGetter(int resultOperand, const GetByIdVariant&, Node* thisNode, unsigned identifierNumber, SpeculatedType prediction);
+    bool handleModuleNamespaceLoad(int resultOperand, SpeculatedType, Node* base, GetByIdStatus);
 
     // Create a presence ObjectPropertyCondition based on some known offset and structure set. Does not
     // check the validity of the condition, but it may return a null one if it encounters a contradiction.
@@ -2844,6 +2846,34 @@
     return true;
 }
 
+bool ByteCodeParser::handleModuleNamespaceLoad(int resultOperand, SpeculatedType prediction, Node* base, GetByIdStatus getById)
+{
+    if (m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell))
+        return false;
+    addToGraph(CheckCell, OpInfo(m_graph.freeze(getById.moduleNamespaceObject())), Edge(base, CellUse));
+
+    // Ideally we wouldn't have to do this Phantom. But:
+    //
+    // For the constant case: we must do it because otherwise we would have no way of knowing
+    // that the scope is live at OSR here.
+    //
+    // For the non-constant case: GetClosureVar could be DCE'd, but baseline's implementation
+    // won't be able to handle an Undefined scope.
+    addToGraph(Phantom, base);
+
+    // Constant folding in the bytecode parser is important for performance. This may not
+    // have executed yet. If it hasn't, then we won't have a prediction. Lacking a
+    // prediction, we'd otherwise think that it has to exit. Then when it did execute, we
+    // would recompile. But if we can fold it here, we avoid the exit.
+    m_graph.freeze(getById.moduleEnvironment());
+    if (JSValue value = m_graph.tryGetConstantClosureVar(getById.moduleEnvironment(), getById.scopeOffset())) {
+        set(VirtualRegister(resultOperand), weakJSConstant(value));
+        return true;
+    }
+    set(VirtualRegister(resultOperand), addToGraph(GetClosureVar, OpInfo(getById.scopeOffset().offset()), OpInfo(prediction), weakJSConstant(getById.moduleEnvironment())));
+    return true;
+}
+
 template<typename ChecksFunctor>
 bool ByteCodeParser::handleTypedArrayConstructor(
     int resultOperand, InternalFunction* function, int registerOffset,
@@ -3438,6 +3468,14 @@
     else
         getById = TryGetById;
 
+    if (getById != TryGetById && getByIdStatus.isModuleNamespace()) {
+        if (handleModuleNamespaceLoad(destinationOperand, prediction, base, getByIdStatus)) {
+            if (m_graph.compilation())
+                m_graph.compilation()->noticeInlinedGetById();
+            return;
+        }
+    }
+
     // Special path for custom accessors since custom's offset does not have any meanings.
     // So, this is completely different from Simple one. But we have a chance to optimize it when we use DOMJIT.
     if (Options::useDOMJIT() && getByIdStatus.isCustom()) {

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/AssemblyHelpers.h (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/AssemblyHelpers.h	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/AssemblyHelpers.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -158,6 +158,16 @@
         }
 #endif
     }
+
+    void loadValue(void* address, JSValueRegs regs)
+    {
+#if USE(JSVALUE64)
+        load64(address, regs.gpr());
+#else
+        load32(bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + PayloadOffset), regs.payloadGPR());
+        load32(bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + TagOffset), regs.tagGPR());
+#endif
+    }
     
     // Note that this clobbers offset.
     void loadProperty(GPRReg object, GPRReg offset, JSValueRegs result);

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/Repatch.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/Repatch.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/jit/Repatch.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -46,8 +46,10 @@
 #include "JIT.h"
 #include "JITInlines.h"
 #include "JSCInlines.h"
+#include "JSModuleNamespaceObject.h"
 #include "JSWebAssembly.h"
 #include "LinkBuffer.h"
+#include "ModuleNamespaceAccessCase.h"
 #include "PolymorphicAccess.h"
 #include "ScopedArguments.h"
 #include "ScratchRegisterAllocator.h"
@@ -192,6 +194,11 @@
                 newCase = AccessCase::create(vm, codeBlock, AccessCase::ScopedArgumentsLength);
         }
     }
+
+    if (!propertyName.isSymbol() && isJSModuleNamespaceObject(baseValue) && !slot.isUnset()) {
+        if (auto moduleNamespaceSlot = slot.moduleNamespaceSlot())
+            newCase = ModuleNamespaceAccessCase::create(vm, codeBlock, jsCast<JSModuleNamespaceObject*>(baseValue), moduleNamespaceSlot->environment, ScopeOffset(moduleNamespaceSlot->scopeOffset));
+    }
     
     if (!newCase) {
         if (!slot.isCacheable() && !slot.isUnset())

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -697,9 +697,10 @@
     IdentifierSet exportedNames;
     getExportedNames(exec, this, exportedNames);
 
-    IdentifierSet unambiguousNames;
+    Vector<std::pair<Identifier, Resolution>> resolutions;
     for (auto& name : exportedNames) {
-        const AbstractModuleRecord::Resolution resolution = resolveExport(exec, Identifier::fromUid(exec, name.get()));
+        Identifier ident = Identifier::fromUid(exec, name.get());
+        const Resolution resolution = resolveExport(exec, ident);
         switch (resolution.type) {
         case Resolution::Type::NotFound:
             throwSyntaxError(exec, scope, makeString("Exported binding name '", String(name.get()), "' is not found."));
@@ -713,12 +714,12 @@
             break;
 
         case Resolution::Type::Resolved:
-            unambiguousNames.add(name);
+            resolutions.append({ WTFMove(ident), resolution });
             break;
         }
     }
 
-    m_moduleNamespaceObject.set(vm, this, JSModuleNamespaceObject::create(exec, globalObject, globalObject->moduleNamespaceObjectStructure(), this, unambiguousNames));
+    m_moduleNamespaceObject.set(vm, this, JSModuleNamespaceObject::create(exec, globalObject, globalObject->moduleNamespaceObjectStructure(), this, WTFMove(resolutions)));
     return m_moduleNamespaceObject.get();
 }
 

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleNamespaceObject.cpp (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleNamespaceObject.cpp	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleNamespaceObject.cpp	2017-02-27 13:44:03 UTC (rev 213049)
@@ -41,7 +41,7 @@
 {
 }
 
-void JSModuleNamespaceObject::finishCreation(ExecState* exec, JSGlobalObject*, AbstractModuleRecord* moduleRecord, const IdentifierSet& exports)
+void JSModuleNamespaceObject::finishCreation(ExecState* exec, JSGlobalObject*, AbstractModuleRecord* moduleRecord, Vector<std::pair<Identifier, AbstractModuleRecord::Resolution>>&& resolutions)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -54,17 +54,25 @@
     //     The list is ordered as if an Array of those String values had been sorted using Array.prototype.sort using SortCompare as comparefn.
     //
     // Sort the exported names by the code point order.
-    Vector<UniquedStringImpl*> temporaryVector(exports.size(), nullptr);
-    std::transform(exports.begin(), exports.end(), temporaryVector.begin(), [](const RefPtr<WTF::UniquedStringImpl>& ref) {
-        return ref.get();
+    std::sort(resolutions.begin(), resolutions.end(), [] (const auto& lhs, const auto& rhs) {
+        return codePointCompare(lhs.first.impl(), rhs.first.impl()) < 0;
     });
-    std::sort(temporaryVector.begin(), temporaryVector.end(), [] (UniquedStringImpl* lhs, UniquedStringImpl* rhs) {
-        return codePointCompare(lhs, rhs) < 0;
-    });
-    for (auto* identifier : temporaryVector)
-        m_exports.add(identifier);
 
     m_moduleRecord.set(vm, this, moduleRecord);
+    {
+        unsigned moduleRecordOffset = 0;
+        m_names.reserveCapacity(resolutions.size());
+        for (const auto& pair : resolutions) {
+            moduleRecordAt(moduleRecordOffset).set(vm, this, pair.second.moduleRecord);
+            m_names.append(pair.first);
+            m_exports.add(pair.first.impl(), ExportEntry {
+                pair.second.localName,
+                moduleRecordOffset
+            });
+            ++moduleRecordOffset;
+        }
+    }
+
     putDirect(vm, vm.propertyNames->toStringTagSymbol, jsString(&vm, "Module"), DontEnum | DontDelete | ReadOnly);
 
     // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-getprototypeof
@@ -87,8 +95,24 @@
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Base::visitChildren(thisObject, visitor);
     visitor.append(thisObject->m_moduleRecord);
+    for (unsigned i = 0; i < thisObject->m_names.size(); ++i)
+        visitor.appendHidden(thisObject->moduleRecordAt(i));
 }
 
+static JSValue getValue(JSModuleEnvironment* environment, PropertyName localName, ScopeOffset& scopeOffset)
+{
+    SymbolTable* symbolTable = environment->symbolTable();
+    {
+        ConcurrentJSLocker locker(symbolTable->m_lock);
+        auto iter = symbolTable->find(locker, localName.uid());
+        ASSERT(iter != symbolTable->end(locker));
+        SymbolTableEntry& entry = iter->value;
+        ASSERT(!entry.isNull());
+        scopeOffset = entry.scopeOffset();
+    }
+    return environment->variableAt(scopeOffset).get();
+}
+
 bool JSModuleNamespaceObject::getOwnPropertySlot(JSObject* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
 {
     VM& vm = exec->vm();
@@ -104,31 +128,19 @@
     if (propertyName.isSymbol())
         return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 
-    // FIXME: Add IC for module namespace object.
-    // https://bugs.webkit.org/show_bug.cgi?id=160590
-    slot.disableCaching();
     slot.setIsTaintedByOpaqueObject();
-    if (!thisObject->m_exports.contains(propertyName.uid()))
+
+    auto iterator = thisObject->m_exports.find(propertyName.uid());
+    if (iterator == thisObject->m_exports.end())
         return false;
+    ExportEntry& exportEntry = iterator->value;
 
     switch (slot.internalMethodType()) {
-    case PropertySlot::InternalMethodType::Get:
-    case PropertySlot::InternalMethodType::GetOwnProperty: {
-        AbstractModuleRecord* moduleRecord = thisObject->moduleRecord();
-
-        AbstractModuleRecord::Resolution resolution = moduleRecord->resolveExport(exec, Identifier::fromUid(exec, propertyName.uid()));
-        ASSERT(resolution.type != AbstractModuleRecord::Resolution::Type::NotFound && resolution.type != AbstractModuleRecord::Resolution::Type::Ambiguous);
-
-        AbstractModuleRecord* targetModule = resolution.moduleRecord;
-        JSModuleEnvironment* targetEnvironment = targetModule->moduleEnvironment();
-
-        PropertySlot trampolineSlot(targetEnvironment, PropertySlot::InternalMethodType::Get);
-        bool found = targetEnvironment->methodTable(vm)->getOwnPropertySlot(targetEnvironment, exec, resolution.localName, trampolineSlot);
-        ASSERT_UNUSED(found, found);
-
-        JSValue value = trampolineSlot.getValue(exec, propertyName);
-        ASSERT(!scope.exception());
-
+    case PropertySlot::InternalMethodType::GetOwnProperty:
+    case PropertySlot::InternalMethodType::Get: {
+        JSModuleEnvironment* environment = thisObject->moduleRecordAt(exportEntry.moduleRecordOffset)->moduleEnvironment();
+        ScopeOffset scopeOffset;
+        JSValue value = getValue(environment, exportEntry.localName, scopeOffset);
         // If the value is filled with TDZ value, throw a reference error.
         if (!value) {
             throwVMError(exec, scope, createTDZError(exec));
@@ -135,9 +147,10 @@
             return false;
         }
 
-        slot.setValue(thisObject, DontDelete, value);
+        slot.setValueModuleNamespace(thisObject, DontDelete, value, environment, scopeOffset);
         return true;
     }
+
     case PropertySlot::InternalMethodType::HasProperty: {
         // Do not perform [[Get]] for [[HasProperty]].
         // [[Get]] / [[GetOwnProperty]] onto namespace object could throw an error while [[HasProperty]] just returns true here.
@@ -189,8 +202,8 @@
 {
     // http://www.ecma-international.org/ecma-262/6.0/#sec-module-namespace-exotic-objects-ownpropertykeys
     JSModuleNamespaceObject* thisObject = jsCast<JSModuleNamespaceObject*>(cell);
-    for (const auto& name : thisObject->m_exports)
-        propertyNames.add(name.get());
+    for (const auto& name : thisObject->m_names)
+        propertyNames.add(name.impl());
     return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
 }
 

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleNamespaceObject.h (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleNamespaceObject.h	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleNamespaceObject.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -25,22 +25,25 @@
 
 #pragma once
 
+#include "AbstractModuleRecord.h"
 #include "JSDestructibleObject.h"
-#include <wtf/ListHashSet.h>
+#include "ScopeOffset.h"
 
 namespace JSC {
 
-class AbstractModuleRecord;
-
-class JSModuleNamespaceObject : public JSDestructibleObject {
+class JSModuleNamespaceObject final : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
     static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot | InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | OverridesGetPropertyNames | GetOwnPropertySlotIsImpureForPropertyAbsence | IsImmutablePrototypeExoticObject;
 
-    static JSModuleNamespaceObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, AbstractModuleRecord* moduleRecord, const IdentifierSet& exports)
+    static JSModuleNamespaceObject* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, AbstractModuleRecord* moduleRecord, Vector<std::pair<Identifier, AbstractModuleRecord::Resolution>>&& resolutions)
     {
-        JSModuleNamespaceObject* object = new (NotNull, allocateCell<JSModuleNamespaceObject>(exec->vm().heap)) JSModuleNamespaceObject(exec->vm(), structure);
-        object->finishCreation(exec, globalObject, moduleRecord, exports);
+        JSModuleNamespaceObject* object =
+            new (
+                NotNull,
+                allocateCell<JSModuleNamespaceObject>(exec->vm().heap, JSModuleNamespaceObject::allocationSize(resolutions.size())))
+            JSModuleNamespaceObject(exec->vm(), structure);
+        object->finishCreation(exec, globalObject, moduleRecord, WTFMove(resolutions));
         return object;
     }
 
@@ -61,7 +64,7 @@
     AbstractModuleRecord* moduleRecord() { return m_moduleRecord.get(); }
 
 protected:
-    JS_EXPORT_PRIVATE void finishCreation(ExecState*, JSGlobalObject*, AbstractModuleRecord*, const IdentifierSet& exports);
+    JS_EXPORT_PRIVATE void finishCreation(ExecState*, JSGlobalObject*, AbstractModuleRecord*, Vector<std::pair<Identifier, AbstractModuleRecord::Resolution>>&&);
     JS_EXPORT_PRIVATE JSModuleNamespaceObject(VM&, Structure*);
 
 private:
@@ -68,10 +71,43 @@
     static void destroy(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
 
-    typedef WTF::ListHashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> OrderedIdentifierSet;
+    WriteBarrierBase<AbstractModuleRecord>& moduleRecordAt(unsigned offset)
+    {
+        return moduleRecords()[offset];
+    }
 
-    OrderedIdentifierSet m_exports;
+    WriteBarrierBase<AbstractModuleRecord>* moduleRecords()
+    {
+        return bitwise_cast<WriteBarrierBase<AbstractModuleRecord>*>(bitwise_cast<char*>(this) + offsetOfModuleRecords());
+    }
+
+    static size_t offsetOfModuleRecords()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<AbstractModuleRecord>)>(sizeof(JSModuleNamespaceObject));
+    }
+
+    static size_t allocationSize(unsigned moduleRecords)
+    {
+        return offsetOfModuleRecords() + moduleRecords * sizeof(WriteBarrier<AbstractModuleRecord>);
+    }
+
+    struct ExportEntry {
+        Identifier localName;
+        unsigned moduleRecordOffset;
+    };
+
+    typedef HashMap<RefPtr<UniquedStringImpl>, ExportEntry, IdentifierRepHash, HashTraits<RefPtr<UniquedStringImpl>>> ExportMap;
+
+    ExportMap m_exports;
+    Vector<Identifier> m_names;
     WriteBarrier<AbstractModuleRecord> m_moduleRecord;
 };
 
+inline bool isJSModuleNamespaceObject(JSCell* cell)
+{
+    return cell->classInfo(*cell->vm()) == JSModuleNamespaceObject::info();
+}
+
+inline bool isJSModuleNamespaceObject(JSValue v) { return v.isCell() && isJSModuleNamespaceObject(v.asCell()); }
+
 } // namespace JSC

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleRecord.h (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleRecord.h	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/JSModuleRecord.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -40,11 +40,6 @@
 
     DECLARE_EXPORT_INFO;
 
-    JSModuleEnvironment* moduleEnvironment()
-    {
-        ASSERT(m_moduleEnvironment);
-        return m_moduleEnvironment.get();
-    }
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
     static JSModuleRecord* create(ExecState*, VM&, Structure*, const Identifier&, const SourceCode&, const VariableEnvironment&, const VariableEnvironment&);
 

Modified: releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/PropertySlot.h (213048 => 213049)


--- releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/PropertySlot.h	2017-02-27 13:25:35 UTC (rev 213048)
+++ releases/WebKitGTK/webkit-2.16/Source/_javascript_Core/runtime/PropertySlot.h	2017-02-27 13:44:03 UTC (rev 213049)
@@ -23,6 +23,7 @@
 #include "JSCJSValue.h"
 #include "PropertyName.h"
 #include "PropertyOffset.h"
+#include "ScopeOffset.h"
 #include <wtf/Assertions.h>
 
 namespace JSC {
@@ -32,6 +33,7 @@
 class ExecState;
 class GetterSetter;
 class JSObject;
+class JSModuleEnvironment;
 
 // ECMA 262-3 8.6.1
 // Property attributes
@@ -86,6 +88,12 @@
         VMInquiry, // Our VM is just poking around. When this is the InternalMethodType, getOwnPropertySlot is not allowed to do user observable actions.
     };
 
+    enum class AdditionalDataType : uint8_t {
+        None,
+        DOMJIT, // Annotated with DOMJIT information.
+        ModuleNamespace, // ModuleNamespaceObject's environment access.
+    };
+
     explicit PropertySlot(const JSValue thisValue, InternalMethodType internalMethodType)
         : m_offset(invalidOffset)
         , m_thisValue(thisValue)
@@ -94,6 +102,7 @@
         , m_cacheability(CachingAllowed)
         , m_propertyType(TypeUnset)
         , m_internalMethodType(internalMethodType)
+        , m_additionalDataType(AdditionalDataType::None)
         , m_isTaintedByOpaqueObject(false)
     {
     }
@@ -163,9 +172,23 @@
 
     DOMJIT::GetterSetter* domJIT() const
     {
-        return m_domJIT;
+        if (m_additionalDataType == AdditionalDataType::DOMJIT)
+            return m_additionalData.domJIT;
+        return nullptr;
     }
 
+    struct ModuleNamespaceSlot {
+        JSModuleEnvironment* environment;
+        unsigned scopeOffset;
+    };
+
+    std::optional<ModuleNamespaceSlot> moduleNamespaceSlot() const
+    {
+        if (m_additionalDataType == AdditionalDataType::ModuleNamespace)
+            return m_additionalData.moduleNamespaceSlot;
+        return std::nullopt;
+    }
+
     void setValue(JSObject* slotBase, unsigned attributes, JSValue value)
     {
         ASSERT(attributes == attributesForStructure(attributes));
@@ -206,6 +229,14 @@
         m_offset = invalidOffset;
     }
 
+    void setValueModuleNamespace(JSObject* slotBase, unsigned attributes, JSValue value, JSModuleEnvironment* environment, ScopeOffset scopeOffset)
+    {
+        setValue(slotBase, attributes, value);
+        m_additionalDataType = AdditionalDataType::ModuleNamespace;
+        m_additionalData.moduleNamespaceSlot.environment = environment;
+        m_additionalData.moduleNamespaceSlot.scopeOffset = scopeOffset.offset();
+    }
+
     void setCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue)
     {
         ASSERT(attributes == attributesForStructure(attributes));
@@ -220,7 +251,7 @@
         m_offset = invalidOffset;
     }
     
-    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, DOMJIT::GetterSetter* domJIT = nullptr)
+    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue)
     {
         ASSERT(attributes == attributesForStructure(attributes));
         
@@ -232,9 +263,17 @@
         m_slotBase = slotBase;
         m_propertyType = TypeCustom;
         m_offset = !invalidOffset;
-        m_domJIT = domJIT;
     }
 
+    void setCacheableCustom(JSObject* slotBase, unsigned attributes, GetValueFunc getValue, DOMJIT::GetterSetter* domJIT)
+    {
+        setCacheableCustom(slotBase, attributes, getValue);
+        if (domJIT) {
+            m_additionalDataType = AdditionalDataType::DOMJIT;
+            m_additionalData.domJIT = domJIT;
+        }
+    }
+
     void setCustomGetterSetter(JSObject* slotBase, unsigned attributes, CustomGetterSetter* getterSetter)
     {
         ASSERT(attributes == attributesForStructure(attributes));
@@ -328,7 +367,11 @@
     CacheabilityType m_cacheability;
     PropertyType m_propertyType;
     InternalMethodType m_internalMethodType;
-    DOMJIT::GetterSetter* m_domJIT { nullptr };
+    AdditionalDataType m_additionalDataType;
+    union {
+        DOMJIT::GetterSetter* domJIT;
+        ModuleNamespaceSlot moduleNamespaceSlot;
+    } m_additionalData;
     bool m_isTaintedByOpaqueObject;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to