Unreviewed, rolling out r183789.
https://bugs.webkit.org/show_bug.cgi?id=144620

Causing flakiness on exceptionFuzz tests locally on 32-bit
build (Requested by saamyjoon on #webkit).

Reverted changeset:

"Global functions should be initialized as JSFunctions in byte
code"
https://bugs.webkit.org/show_bug.cgi?id=144178
http://trac.webkit.org/changeset/183789

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@183790 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index 4d5ae2e..f0fe50a 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
+2015-05-04  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r183789.
+        https://bugs.webkit.org/show_bug.cgi?id=144620
+
+        Causing flakiness on exceptionFuzz tests locally on 32-bit
+        build (Requested by saamyjoon on #webkit).
+
+        Reverted changeset:
+
+        "Global functions should be initialized as JSFunctions in byte
+        code"
+        https://bugs.webkit.org/show_bug.cgi?id=144178
+        http://trac.webkit.org/changeset/183789
+
 2015-05-04  Saam Barati  <saambarati1@gmail.com>
 
         Global functions should be initialized as JSFunctions in byte code
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
index 8a80a5c..4a81501 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.cpp
@@ -471,6 +471,8 @@
     UnlinkedProgramCodeBlock* thisObject = jsCast<UnlinkedProgramCodeBlock*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Base::visitChildren(thisObject, visitor);
+    for (size_t i = 0, end = thisObject->m_functionDeclarations.size(); i != end; i++)
+        visitor.append(&thisObject->m_functionDeclarations[i].second);
 }
 
 UnlinkedCodeBlock::~UnlinkedCodeBlock()
diff --git a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
index f4e2455..ca91e4a 100644
--- a/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
+++ b/Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
@@ -654,14 +654,21 @@
 
     static void destroy(JSCell*);
 
+    void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
+    {
+        m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
+    }
+
     void addVariableDeclaration(const Identifier& name, bool isConstant)
     {
         m_varDeclarations.append(std::make_pair(name, isConstant));
     }
 
     typedef Vector<std::pair<Identifier, bool>> VariableDeclations;
+    typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations;
 
     const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
+    const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
@@ -672,6 +679,7 @@
     }
 
     VariableDeclations m_varDeclarations;
+    FunctionDeclations m_functionDeclarations;
 
 public:
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index c3ce875..2f21e49 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -77,17 +77,9 @@
 
     {
         RefPtr<RegisterID> temp = newTemporary();
-        RefPtr<RegisterID> globalScope = scopeRegister(); // FIXME: With lexical scoping, this won't always be the global object: https://bugs.webkit.org/show_bug.cgi?id=142944 
-        for (auto functionPair : m_functionsToInitialize) {
-            FunctionBodyNode* functionBody = functionPair.first;
-            FunctionVariableType functionType = functionPair.second;
+        for (FunctionBodyNode* functionBody : m_functionsToInitialize) {
             emitNewFunction(temp.get(), functionBody);
-            if (functionType == NormalFunctionVariable)
-                initializeVariable(variable(functionBody->ident()) , temp.get());
-            else if (functionType == GlobalFunctionVariable)
-                emitPutToScope(globalScope.get(), Variable(functionBody->ident()), temp.get(), ThrowIfNotFound);
-            else
-                RELEASE_ASSERT_NOT_REACHED();
+            initializeVariable(variable(functionBody->ident()), temp.get());
         }
     }
     
@@ -171,7 +163,8 @@
 
     for (size_t i = 0; i < functionStack.size(); ++i) {
         FunctionBodyNode* function = functionStack[i];
-        m_functionsToInitialize.append(std::make_pair(function, GlobalFunctionVariable));
+        UnlinkedFunctionExecutable* unlinkedFunction = makeFunction(function);
+        codeBlock->addFunctionDeclaration(*m_vm, function->ident(), unlinkedFunction);
     }
 
     for (size_t i = 0; i < varStack.size(); ++i)
@@ -391,7 +384,7 @@
     for (FunctionBodyNode* function : functionNode->functionStack()) {
         const Identifier& ident = function->ident();
         createVariable(ident, varKind(ident.impl()), IsVariable);
-        m_functionsToInitialize.append(std::make_pair(function, NormalFunctionVariable));
+        m_functionsToInitialize.append(function);
     }
     for (auto& entry : functionNode->varStack()) {
         ConstantMode constantMode = modeForIsConstant(entry.second & DeclarationStacks::IsConstant);
diff --git a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index b815632..9af8d4f 100644
--- a/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -744,8 +744,7 @@
         Vector<std::unique_ptr<ForInContext>> m_forInContextStack;
         Vector<TryContext> m_tryContextStack;
         Vector<std::pair<RefPtr<RegisterID>, const DeconstructionPatternNode*>> m_deconstructedParameters;
-        enum FunctionVariableType : uint8_t { NormalFunctionVariable, GlobalFunctionVariable };
-        Vector<std::pair<FunctionBodyNode*, FunctionVariableType>> m_functionsToInitialize;
+        Vector<FunctionBodyNode*> m_functionsToInitialize;
         bool m_needToInitializeArguments { false };
         
         Vector<TryRange> m_tryRanges;
diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp
index 35092cc..394db0e 100644
--- a/Source/JavaScriptCore/runtime/Executable.cpp
+++ b/Source/JavaScriptCore/runtime/Executable.cpp
@@ -510,11 +510,12 @@
     BatchedTransitionOptimizer optimizer(vm, globalObject);
 
     const UnlinkedProgramCodeBlock::VariableDeclations& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
+    const UnlinkedProgramCodeBlock::FunctionDeclations& functionDeclarations = unlinkedCodeBlock->functionDeclarations();
 
-    for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) {
-        UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i);
-        ASSERT(!unlinkedFunctionExecutable->name().isEmpty());
-        globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name());
+    for (size_t i = 0; i < functionDeclarations.size(); ++i) {
+        UnlinkedFunctionExecutable* unlinkedFunctionExecutable = functionDeclarations[i].second.get();
+        JSValue value = JSFunction::create(vm, unlinkedFunctionExecutable->link(vm, m_source), scope);
+        globalObject->addFunction(callFrame, functionDeclarations[i].first, value);
         if (vm.typeProfiler() || vm.controlFlowProfiler()) {
             vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), 
                 unlinkedFunctionExecutable->typeProfilingStartOffset(), 
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
index 7d06fa6..9f86e73 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -502,12 +502,16 @@
     return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
 }
 
-void JSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode)
+JSGlobalObject::NewGlobalVar JSGlobalObject::addGlobalVar(const Identifier& ident, ConstantMode constantMode)
 {
     ConcurrentJITLocker locker(symbolTable()->m_lock);
     SymbolTableEntry entry = symbolTable()->get(locker, ident.impl());
-    if (!entry.isNull())
-        return;
+    if (!entry.isNull()) {
+        NewGlobalVar result;
+        result.offset = entry.scopeOffset();
+        result.set = entry.watchpointSet();
+        return result;
+    }
     
     ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker);
     SymbolTableEntry newEntry(VarOffset(offset), (constantMode == IsConstant) ? ReadOnly : 0);
@@ -519,13 +523,21 @@
     
     ScopeOffset offsetForAssert = addVariables(1);
     RELEASE_ASSERT(offsetForAssert == offset);
+
+    NewGlobalVar var;
+    var.offset = offset;
+    var.set = newEntry.watchpointSet();
+    return var;
 }
 
-void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName)
+void JSGlobalObject::addFunction(ExecState* exec, const Identifier& propertyName, JSValue value)
 {
     VM& vm = exec->vm();
     removeDirect(vm, propertyName); // Newly declared functions overwrite existing properties.
-    addGlobalVar(propertyName, IsVariable);
+    NewGlobalVar var = addGlobalVar(propertyName, IsVariable);
+    variableAt(var.offset).set(exec->vm(), this, value);
+    if (var.set)
+        var.set->touch(VariableWriteFireDetail(this, propertyName));
 }
 
 static inline JSObject* lastInPrototypeChain(JSObject* object)
diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h
index 47f7c26..7acc1dd 100644
--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h
@@ -338,7 +338,11 @@
         setGlobalThis(vm, thisValue);
     }
 
-    void addGlobalVar(const Identifier&, ConstantMode);
+    struct NewGlobalVar {
+        ScopeOffset offset;
+        WatchpointSet* set;
+    };
+    NewGlobalVar addGlobalVar(const Identifier&, ConstantMode);
 
 public:
     JS_EXPORT_PRIVATE ~JSGlobalObject();
@@ -370,7 +374,7 @@
         if (!hasProperty(exec, propertyName))
             addGlobalVar(propertyName, IsConstant);
     }
-    void addFunction(ExecState*, const Identifier&);
+    void addFunction(ExecState*, const Identifier&, JSValue);
 
     // The following accessors return pristine values, even if a script 
     // replaces the global object's associated property.