Scopes should always be created with a previously-created symbol table rather than...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Feb 2015 21:54:15 +0000 (21:54 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Feb 2015 21:54:15 +0000 (21:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=141915

Reviewed by Mark Lam.

The main effect of this change is that pushing name scopes no longer requires creating symbol
tables on the fly.

This also makes it so that JSEnvironmentRecords must always have an a priori symbol table.

JSSegmentedVariableObject still does a hack where it creates a blank symbol table on-demand.
This is needed because that's what JSGlobalObject and all of its many subclasses want. That's
harmless; I mainly needed a prior symbol tables for JSEnvironmentRecords anyway.

* bytecode/BytecodeList.json:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitPushFunctionNameScope):
(JSC::BytecodeGenerator::emitPushCatchScope):
* jit/CCallHelpers.h:
(JSC::CCallHelpers::setupArgumentsWithExecState):
* jit/JIT.h:
* jit/JITInlines.h:
(JSC::JIT::callOperation):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_push_name_scope):
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::emit_op_push_name_scope):
* jit/JITOperations.cpp:
(JSC::pushNameScope):
* jit/JITOperations.h:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* llint/LowLevelInterpreter.asm:
* runtime/Executable.cpp:
(JSC::ScriptExecutable::newCodeBlockFor):
* runtime/JSCatchScope.h:
(JSC::JSCatchScope::JSCatchScope):
(JSC::JSCatchScope::create):
* runtime/JSEnvironmentRecord.h:
(JSC::JSEnvironmentRecord::JSEnvironmentRecord):
* runtime/JSFunctionNameScope.h:
(JSC::JSFunctionNameScope::JSFunctionNameScope):
(JSC::JSFunctionNameScope::create):
* runtime/JSNameScope.cpp:
(JSC::JSNameScope::create):
* runtime/JSNameScope.h:
(JSC::JSNameScope::create):
(JSC::JSNameScope::finishCreation):
(JSC::JSNameScope::JSNameScope):
* runtime/JSSegmentedVariableObject.h:
(JSC::JSSegmentedVariableObject::finishCreation):
* runtime/JSSymbolTableObject.h:
(JSC::JSSymbolTableObject::JSSymbolTableObject):
(JSC::JSSymbolTableObject::finishCreation): Deleted.
* runtime/SymbolTable.h:
(JSC::SymbolTable::createNameScopeTable):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@180514 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bytecode/BytecodeList.json
Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/JIT.h
Source/JavaScriptCore/jit/JITInlines.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/runtime/Executable.cpp
Source/JavaScriptCore/runtime/JSCatchScope.h
Source/JavaScriptCore/runtime/JSEnvironmentRecord.h
Source/JavaScriptCore/runtime/JSFunctionNameScope.h
Source/JavaScriptCore/runtime/JSNameScope.cpp
Source/JavaScriptCore/runtime/JSNameScope.h
Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h
Source/JavaScriptCore/runtime/JSSymbolTableObject.h
Source/JavaScriptCore/runtime/SymbolTable.h

index fab5b9b..c6c3097 100644 (file)
@@ -1,5 +1,64 @@
 2015-02-23  Filip Pizlo  <fpizlo@apple.com>
 
+        Scopes should always be created with a previously-created symbol table rather than creating one on the fly
+        https://bugs.webkit.org/show_bug.cgi?id=141915
+
+        Reviewed by Mark Lam.
+        
+        The main effect of this change is that pushing name scopes no longer requires creating symbol
+        tables on the fly.
+        
+        This also makes it so that JSEnvironmentRecords must always have an a priori symbol table.
+        
+        JSSegmentedVariableObject still does a hack where it creates a blank symbol table on-demand.
+        This is needed because that's what JSGlobalObject and all of its many subclasses want. That's
+        harmless; I mainly needed a prior symbol tables for JSEnvironmentRecords anyway.
+
+        * bytecode/BytecodeList.json:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitPushFunctionNameScope):
+        (JSC::BytecodeGenerator::emitPushCatchScope):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::setupArgumentsWithExecState):
+        * jit/JIT.h:
+        * jit/JITInlines.h:
+        (JSC::JIT::callOperation):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOpcodes32_64.cpp:
+        (JSC::JIT::emit_op_push_name_scope):
+        * jit/JITOperations.cpp:
+        (JSC::pushNameScope):
+        * jit/JITOperations.h:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        * llint/LowLevelInterpreter.asm:
+        * runtime/Executable.cpp:
+        (JSC::ScriptExecutable::newCodeBlockFor):
+        * runtime/JSCatchScope.h:
+        (JSC::JSCatchScope::JSCatchScope):
+        (JSC::JSCatchScope::create):
+        * runtime/JSEnvironmentRecord.h:
+        (JSC::JSEnvironmentRecord::JSEnvironmentRecord):
+        * runtime/JSFunctionNameScope.h:
+        (JSC::JSFunctionNameScope::JSFunctionNameScope):
+        (JSC::JSFunctionNameScope::create):
+        * runtime/JSNameScope.cpp:
+        (JSC::JSNameScope::create):
+        * runtime/JSNameScope.h:
+        (JSC::JSNameScope::create):
+        (JSC::JSNameScope::finishCreation):
+        (JSC::JSNameScope::JSNameScope):
+        * runtime/JSSegmentedVariableObject.h:
+        (JSC::JSSegmentedVariableObject::finishCreation):
+        * runtime/JSSymbolTableObject.h:
+        (JSC::JSSymbolTableObject::JSSymbolTableObject):
+        (JSC::JSSymbolTableObject::finishCreation): Deleted.
+        * runtime/SymbolTable.h:
+        (JSC::SymbolTable::createNameScopeTable):
+
+2015-02-23  Filip Pizlo  <fpizlo@apple.com>
+
         Add a comment to clarify that the test was taken from the bug report, in response to
         feedback from Michael Saboff and Benjamin Poulain.
         
index ec6c54c..5c1f0d8 100644 (file)
             { "name" : "op_put_to_scope", "length" : 7 },
             { "name" : "op_push_with_scope", "length" : 3 },
             { "name" : "op_pop_scope", "length" : 2 },
-            { "name" : "op_push_name_scope", "length" : 6 },
+            { "name" : "op_push_name_scope", "length" : 5 },
             { "name" : "op_catch", "length" : 2 },
             { "name" : "op_throw", "length" : 2 },
             { "name" : "op_throw_static_error", "length" : 3 },
index 6f67529..a02f2bb 100644 (file)
@@ -2394,9 +2394,8 @@ void BytecodeGenerator::emitPushFunctionNameScope(RegisterID* dst, const Identif
 {
     emitOpcode(op_push_name_scope);
     instructions().append(dst->index());
-    instructions().append(addConstant(property));
     instructions().append(value->index());
-    instructions().append(attributes);
+    instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
     instructions().append(JSNameScope::FunctionNameScope);
 }
 
@@ -2409,9 +2408,8 @@ void BytecodeGenerator::emitPushCatchScope(RegisterID* dst, const Identifier& pr
 
     emitOpcode(op_push_name_scope);
     instructions().append(dst->index());
-    instructions().append(addConstant(property));
     instructions().append(value->index());
-    instructions().append(attributes);
+    instructions().append(addConstantValue(SymbolTable::createNameScopeTable(*vm(), property, attributes))->index());
     instructions().append(JSNameScope::CatchScope);
 }
 
index 685c12a..78efcf4 100644 (file)
@@ -436,6 +436,16 @@ public:
         addCallArgument(arg5);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
+    {
+        resetCallArguments();
+        addCallArgument(GPRInfo::callFrameRegister);
+        addCallArgument(arg1);
+        addCallArgument(arg2);
+        addCallArgument(arg3);
+        addCallArgument(arg4);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5)
     {
         resetCallArguments();
@@ -1619,6 +1629,12 @@ public:
         setupArgumentsWithExecState(arg1, arg2, arg3);
     }
 
+    ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4)
+    {
+        poke(arg4, POKE_ARGUMENT_OFFSET);
+        setupArgumentsWithExecState(arg1, arg2, arg3);
+    }
+
     ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImm32 arg5)
     {
         poke(arg5, POKE_ARGUMENT_OFFSET + 1);
index 9b7ac09..dd86d8e 100644 (file)
@@ -717,11 +717,7 @@ namespace JSC {
         MacroAssembler::Call callOperation(V_JITOperation_ECC, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_ECICC, RegisterID, const Identifier*, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(J_JITOperation_EE, RegisterID);
-#if USE(JSVALUE64)
-        MacroAssembler::Call callOperation(V_JITOperation_EZIdJZZ, int, const Identifier*, RegisterID, int32_t, int32_t);
-#else
-        MacroAssembler::Call callOperation(V_JITOperation_EZIdJZ, int, const Identifier*, RegisterID, int32_t);
-#endif
+        MacroAssembler::Call callOperation(V_JITOperation_EZSymtabJ, int, SymbolTable*, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID);
 #if USE(JSVALUE64)
         MacroAssembler::Call callOperationNoExceptionCheck(V_JITOperation_EJ, RegisterID);
@@ -754,7 +750,7 @@ namespace JSC {
         MacroAssembler::Call callOperation(P_JITOperation_EJS, GPRReg, GPRReg, size_t);
         MacroAssembler::Call callOperation(S_JITOperation_EJ, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(S_JITOperation_EJJ, RegisterID, RegisterID, RegisterID, RegisterID);
-        MacroAssembler::Call callOperation(V_JITOperation_EZIdJZ, int, const Identifier*, RegisterID, RegisterID, int32_t);
+        MacroAssembler::Call callOperation(V_JITOperation_EZSymtabJ, int, SymbolTable*, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJ, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJJJ, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID, RegisterID);
         MacroAssembler::Call callOperation(V_JITOperation_EJZ, RegisterID, RegisterID, int32_t);
index 62a4954..79969a6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -460,9 +460,9 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(S_JITOperation_EJJ operati
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZIdJZZ operation, int op1, const Identifier* identOp2, RegisterID regOp3, int32_t op4, int32_t op5)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZSymtabJ operation, int op1, SymbolTable* symbolTable, RegisterID regOp3)
 {
-    setupArgumentsWithExecState(TrustedImm32(op1), TrustedImmPtr(identOp2), regOp3, TrustedImm32(op4), TrustedImm32(op5));
+    setupArgumentsWithExecState(TrustedImm32(op1), TrustedImmPtr(symbolTable), regOp3);
     return appendCallWithExceptionCheck(operation);
 }
 
@@ -594,9 +594,9 @@ ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EJ operatio
     return appendCallWithExceptionCheck(operation);
 }
 
-ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZIdJZ operation, int32_t op1, const Identifier* identOp2, RegisterID regOp3Tag, RegisterID regOp3Payload, int32_t op4)
+ALWAYS_INLINE MacroAssembler::Call JIT::callOperation(V_JITOperation_EZSymtabJ operation, int32_t op1, SymbolTable* symbolTable, RegisterID regOp3Tag, RegisterID regOp3Payload)
 {
-    setupArgumentsWithExecState(TrustedImm32(op1), TrustedImmPtr(identOp2), EABI_32BIT_DUMMY_ARG regOp3Payload, regOp3Tag, TrustedImm32(op4));
+    setupArgumentsWithExecState(TrustedImm32(op1), TrustedImmPtr(symbolTable), EABI_32BIT_DUMMY_ARG regOp3Payload, regOp3Tag);
     return appendCallWithExceptionCheck(operation);
 }
 
index 3a28a62..583e529 100644 (file)
@@ -37,6 +37,7 @@
 #include "JSArray.h"
 #include "JSCell.h"
 #include "JSFunction.h"
+#include "JSNameScope.h"
 #include "JSPropertyNameEnumerator.h"
 #include "LinkBuffer.h"
 #include "MaxFrameExtentForSlowPathCall.h"
@@ -486,8 +487,14 @@ void JIT::emit_op_to_number(Instruction* currentInstruction)
 void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
-    callOperation(operationPushNameScope, dst, &m_codeBlock->identifier(currentInstruction[2].u.operand), regT0, currentInstruction[4].u.operand, currentInstruction[5].u.operand);
+    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
+    if (currentInstruction[4].u.operand == JSNameScope::CatchScope) {
+        callOperation(operationPushCatchScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT0);
+        return;
+    }
+
+    RELEASE_ASSERT(currentInstruction[4].u.operand == JSNameScope::FunctionNameScope);
+    callOperation(operationPushFunctionNameScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT0);
 }
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
index 7a81c6b..cc85349 100644 (file)
@@ -779,14 +779,14 @@ void JIT::emitSlow_op_to_number(Instruction* currentInstruction, Vector<SlowCase
 void JIT::emit_op_push_name_scope(Instruction* currentInstruction)
 {
     int dst = currentInstruction[1].u.operand;
-    emitLoad(currentInstruction[3].u.operand, regT1, regT0);
-    if (currentInstruction[5].u.operand == JSNameScope::CatchScope) {
-        callOperation(operationPushCatchScope, dst, &m_codeBlock->identifier(currentInstruction[2].u.operand), regT1, regT0, currentInstruction[4].u.operand);
+    emitLoad(currentInstruction[2].u.operand, regT1, regT0);
+    if (currentInstruction[4].u.operand == JSNameScope::CatchScope) {
+        callOperation(operationPushCatchScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT1, regT0);
         return;
     }
 
-    RELEASE_ASSERT(currentInstruction[5].u.operand == JSNameScope::FunctionNameScope);
-    callOperation(operationPushFunctionNameScope, dst, &m_codeBlock->identifier(currentInstruction[2].u.operand), regT1, regT0, currentInstruction[4].u.operand);
+    RELEASE_ASSERT(currentInstruction[4].u.operand == JSNameScope::FunctionNameScope);
+    callOperation(operationPushFunctionNameScope, dst, jsCast<SymbolTable*>(getConstantOperand(currentInstruction[3].u.operand)), regT1, regT0);
 }
 
 void JIT::emit_op_catch(Instruction* currentInstruction)
index 72cff99..6f9d92e 100644 (file)
@@ -44,6 +44,8 @@
 #include "JIT.h"
 #include "JITToDFGDeferredCompilationCallback.h"
 #include "JSCInlines.h"
+#include "JSCatchScope.h"
+#include "JSFunctionNameScope.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSNameScope.h"
 #include "JSPropertyNameEnumerator.h"
 
 namespace JSC {
 
+template<typename ScopeType>
+void pushNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
+{
+    VM& vm = exec->vm();
+    NativeCallFrameTracer tracer(&vm, exec);
+    
+    ASSERT(!JITCode::isOptimizingJIT(exec->codeBlock()->jitType()));
+
+    // FIXME: This won't work if this operation is called from the DFG or FTL.
+    // This should be changed to pass in the new scope.
+    JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
+    JSNameScope* scope = ScopeType::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, JSValue::decode(encodedValue));
+
+    // FIXME: This won't work if this operation is called from the DFG or FTL.
+    // This should be changed to return the new scope.
+    exec->uncheckedR(dst) = scope;
+}
+
 extern "C" {
 
 #if COMPILER(MSVC)
@@ -1269,34 +1289,16 @@ void JIT_OPERATION operationPutGetterSetter(ExecState* exec, JSCell* object, Ide
 }
 #endif
 
-void JIT_OPERATION operationPushNameScope(ExecState* exec, int32_t dst, Identifier* identifier, EncodedJSValue encodedValue, int32_t attibutes, int32_t type)
+void JIT_OPERATION operationPushCatchScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
 {
-    VM& vm = exec->vm();
-    NativeCallFrameTracer tracer(&vm, exec);
-
-    // FIXME: This won't work if this operation is called from the DFG or FTL.
-    // This should be changed to pass in the new scope.
-    JSScope* currentScope = exec->uncheckedR(dst).Register::scope();
-    JSNameScope::Type scopeType = static_cast<JSNameScope::Type>(type);
-    JSNameScope* scope = JSNameScope::create(vm, exec->lexicalGlobalObject(), currentScope, *identifier, JSValue::decode(encodedValue), attibutes, scopeType);
-
-    // FIXME: This won't work if this operation is called from the DFG or FTL.
-    // This should be changed to return the new scope.
-    exec->uncheckedR(dst) = scope;
+    pushNameScope<JSCatchScope>(exec, dst, symbolTable, encodedValue);
 }
 
-#if USE(JSVALUE32_64)
-void JIT_OPERATION operationPushCatchScope(ExecState* exec, int32_t dst, Identifier* identifier, EncodedJSValue encodedValue, int32_t attibutes)
+void JIT_OPERATION operationPushFunctionNameScope(ExecState* exec, int32_t dst, SymbolTable* symbolTable, EncodedJSValue encodedValue)
 {
-    operationPushNameScope(exec, dst, identifier, encodedValue, attibutes, JSNameScope::CatchScope);
+    pushNameScope<JSFunctionNameScope>(exec, dst, symbolTable, encodedValue);
 }
 
-void JIT_OPERATION operationPushFunctionNameScope(ExecState* exec, int32_t dst, Identifier* identifier, EncodedJSValue encodedValue, int32_t attibutes)
-{
-    operationPushNameScope(exec, dst, identifier, encodedValue, attibutes, JSNameScope::FunctionNameScope);
-}
-#endif
-
 void JIT_OPERATION operationPushWithScope(ExecState* exec, int32_t dst, EncodedJSValue encodedValue)
 {
     VM& vm = exec->vm();
index 763c0dd..ca23bdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -81,6 +81,7 @@ extern "C" {
     Sprt: SlowPathReturnType
     Ssi: StructureStubInfo*
     St: Structure*
+    Symtab: SymbolTable*
     V: void
     Vm: VM*
     Vws: VariableWatchpointSet*
@@ -170,11 +171,7 @@ typedef void JIT_OPERATION (*V_JITOperation_ECJJ)(ExecState*, JSCell*, EncodedJS
 typedef void JIT_OPERATION (*V_JITOperation_ECPSPS)(ExecState*, JSCell*, void*, size_t, void*, size_t);
 typedef void JIT_OPERATION (*V_JITOperation_ECZ)(ExecState*, JSCell*, int32_t);
 typedef void JIT_OPERATION (*V_JITOperation_ECC)(ExecState*, JSCell*, JSCell*);
-#if USE(JSVALUE64)
-typedef void JIT_OPERATION (*V_JITOperation_EZIdJZZ)(ExecState*, int, Identifier*, EncodedJSValue, int32_t, int32_t);
-#else
-typedef void JIT_OPERATION (*V_JITOperation_EZIdJZ)(ExecState*, int, Identifier*, EncodedJSValue, int32_t);
-#endif
+typedef void JIT_OPERATION (*V_JITOperation_EZSymtabJ)(ExecState*, int32_t, SymbolTable*, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJ)(ExecState*, EncodedJSValue);
 typedef void JIT_OPERATION (*V_JITOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, StringImpl*);
 typedef void JIT_OPERATION (*V_JITOperation_EJIdJJ)(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue, EncodedJSValue);
@@ -288,10 +285,9 @@ void JIT_OPERATION operationPutByIndex(ExecState*, EncodedJSValue, int32_t, Enco
 void JIT_OPERATION operationPutGetterSetter(ExecState*, EncodedJSValue, Identifier*, EncodedJSValue, EncodedJSValue) WTF_INTERNAL;
 #else
 void JIT_OPERATION operationPutGetterSetter(ExecState*, JSCell*, Identifier*, JSCell*, JSCell*) WTF_INTERNAL;
-void JIT_OPERATION operationPushCatchScope(ExecState*, int32_t, Identifier*, EncodedJSValue, int32_t) WTF_INTERNAL;
-void JIT_OPERATION operationPushFunctionNameScope(ExecState*, int32_t, Identifier*, EncodedJSValue, int32_t) WTF_INTERNAL;
 #endif
-void JIT_OPERATION operationPushNameScope(ExecState*, int32_t, Identifier*, EncodedJSValue, int32_t, int32_t) WTF_INTERNAL;
+void JIT_OPERATION operationPushCatchScope(ExecState*, int32_t, SymbolTable*, EncodedJSValue) WTF_INTERNAL;
+void JIT_OPERATION operationPushFunctionNameScope(ExecState*, int32_t, SymbolTable*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationPushWithScope(ExecState*, int32_t, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationPopScope(ExecState*, int32_t) WTF_INTERNAL;
 void JIT_OPERATION operationProfileDidCall(ExecState*, EncodedJSValue) WTF_INTERNAL;
index f59aaac..2787614 100644 (file)
@@ -1286,11 +1286,12 @@ LLINT_SLOW_PATH_DECL(slow_path_pop_scope)
 LLINT_SLOW_PATH_DECL(slow_path_push_name_scope)
 {
     LLINT_BEGIN();
-    CodeBlock* codeBlock = exec->codeBlock();
     int scopeReg = pc[1].u.operand;
     JSScope* currentScope = exec->uncheckedR(scopeReg).Register::scope();
-    JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[5].u.operand);
-    JSNameScope* scope = JSNameScope::create(vm, exec->lexicalGlobalObject(), currentScope, codeBlock->identifier(pc[2].u.operand), LLINT_OP(3).jsValue(), pc[4].u.operand, type);
+    JSValue value = LLINT_OP_C(2).jsValue();
+    SymbolTable* symbolTable = jsCast<SymbolTable*>(LLINT_OP_C(3).jsValue());
+    JSNameScope::Type type = static_cast<JSNameScope::Type>(pc[4].u.operand);
+    JSNameScope* scope = JSNameScope::create(vm, exec->lexicalGlobalObject(), currentScope, symbolTable, value, type);
     exec->uncheckedR(scopeReg) = scope;
     LLINT_END();
 }
index b7bdc03..7681583 100644 (file)
@@ -1256,7 +1256,7 @@ _llint_op_pop_scope:
 _llint_op_push_name_scope:
     traceExecution()
     callSlowPath(_llint_slow_path_push_name_scope)
-    dispatch(6)
+    dispatch(5)
 
 
 _llint_op_throw:
index dfce29f..c5a340b 100644 (file)
@@ -253,8 +253,10 @@ PassRefPtr<CodeBlock> ScriptExecutable::newCodeBlockFor(
         // We shouldn't have to do this. But we do, because bytecode linking requires a real scope
         // chain.
         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=141885
+        SymbolTable* symbolTable =
+            SymbolTable::createNameScopeTable(*vm, executable->name(), ReadOnly | DontDelete);
         scope = JSFunctionNameScope::create(
-            *vm, scope->globalObject(), scope, executable->name(), function, ReadOnly | DontDelete);
+            *vm, scope->globalObject(), scope, symbolTable, function);
     }
     
     SourceProvider* provider = executable->source().provider();
index ee66b8e..0eeab90 100644 (file)
@@ -37,15 +37,15 @@ public:
 private:
     friend class JSNameScope;
     
-    JSCatchScope(VM& vm, JSGlobalObject* globalObject, JSScope* next)
-        : Base(vm, globalObject->catchScopeStructure(), next)
+    JSCatchScope(VM& vm, JSGlobalObject* globalObject, JSScope* next, SymbolTable* symbolTable)
+        : Base(vm, globalObject->catchScopeStructure(), next, symbolTable)
     {
     }
     
 public:
-    static JSCatchScope* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, const Identifier& identifier, JSValue value, unsigned attributes)
+    static JSCatchScope* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
     {
-        return Base::create<JSCatchScope>(vm, globalObject, currentScope, identifier, value, attributes);
+        return Base::create<JSCatchScope>(vm, globalObject, currentScope, symbolTable, value);
     }
     
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
index b4a7751..655db7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2012, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,7 +62,7 @@ protected:
         Structure* structure,
         Register* registers,
         JSScope* scope,
-        SymbolTable* symbolTable = 0)
+        SymbolTable* symbolTable)
         : Base(vm, structure, scope, symbolTable)
         , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers))
     {
index c7d0265..922e89a 100644 (file)
@@ -37,15 +37,15 @@ public:
 private:
     friend class JSNameScope;
     
-    JSFunctionNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next)
-        : Base(vm, globalObject->catchScopeStructure(), next)
+    JSFunctionNameScope(VM& vm, JSGlobalObject* globalObject, JSScope* next, SymbolTable* symbolTable)
+        : Base(vm, globalObject->catchScopeStructure(), next, symbolTable)
     {
     }
     
 public:
-    static JSFunctionNameScope* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, const Identifier& identifier, JSValue value, unsigned attributes)
+    static JSFunctionNameScope* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
     {
-        return Base::create<JSFunctionNameScope>(vm, globalObject, currentScope, identifier, value, attributes);
+        return Base::create<JSFunctionNameScope>(vm, globalObject, currentScope, symbolTable, value);
     }
     
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
index 01a2b72..d092555 100644 (file)
@@ -35,13 +35,13 @@ namespace JSC {
 
 const ClassInfo JSNameScope::s_info = { "NameScope", &Base::s_info, 0, CREATE_METHOD_TABLE(JSNameScope) };
 
-JSNameScope* JSNameScope::create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, const Identifier& identifier, JSValue value, unsigned attributes, Type type)
+JSNameScope* JSNameScope::create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value, Type type)
 {
     switch (type) {
     case CatchScope:
-        return JSCatchScope::create(vm, globalObject, currentScope, identifier, value, attributes);
+        return JSCatchScope::create(vm, globalObject, currentScope, symbolTable, value);
     case FunctionNameScope:
-        return JSFunctionNameScope::create(vm, globalObject, currentScope, identifier, value, attributes);
+        return JSFunctionNameScope::create(vm, globalObject, currentScope, symbolTable, value);
     }
     RELEASE_ASSERT_NOT_REACHED();
     return nullptr;
index 55d3c0c..e0bc16b 100644 (file)
@@ -42,14 +42,14 @@ public:
     };
 
     template<typename T>
-    static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, const Identifier& identifier, JSValue value, unsigned attributes)
+    static T* create(VM& vm, JSGlobalObject* globalObject, JSScope* currentScope, SymbolTable* symbolTable, JSValue value)
     {
-        T* scopeObject = new (NotNull, allocateCell<T>(vm.heap)) T(vm, globalObject, currentScope);
-        scopeObject->finishCreation(vm, identifier, value, attributes);
+        T* scopeObject = new (NotNull, allocateCell<T>(vm.heap)) T(vm, globalObject, currentScope, symbolTable);
+        scopeObject->finishCreation(vm, value);
         return scopeObject;
     }
     
-    static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, const Identifier&, JSValue, unsigned attributes, Type);
+    static JSNameScope* create(VM&, JSGlobalObject*, JSScope* currentScope, SymbolTable*, JSValue, Type);
 
     static void visitChildren(JSCell*, SlotVisitor&);
     static JSValue toThis(JSCell*, ExecState*, ECMAMode);
@@ -61,22 +61,16 @@ public:
     JSValue value() const { return m_registerStore.get(); }
 
 protected:
-    void finishCreation(VM& vm, const Identifier& identifier, JSValue value, unsigned attributes)
+    void finishCreation(VM& vm, JSValue value)
     {
         Base::finishCreation(vm);
         m_registerStore.set(vm, this, value);
-        symbolTable()->add(identifier.impl(), SymbolTableEntry(-1, attributes));
     }
 
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | Base::StructureFlags;
 
-    JSNameScope(VM& vm, Structure* structure, JSScope* next)
-        : Base(
-            vm,
-            structure,
-            reinterpret_cast<Register*>(&m_registerStore + 1),
-            next
-        )
+    JSNameScope(VM& vm, Structure* structure, JSScope* next, SymbolTable* symbolTable)
+        : Base(vm, structure, reinterpret_cast<Register*>(&m_registerStore + 1), next, symbolTable)
     {
     }
 
index 608ecbf..4408734 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -87,6 +87,7 @@ protected:
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
+        m_symbolTable.set(vm, this, SymbolTable::create(vm));
     }
     
     SegmentedVector<WriteBarrier<Unknown>, 16> m_registers;
index 2cd9d1b..af16176 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -50,18 +50,16 @@ public:
 protected:
     static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetPropertyNames | Base::StructureFlags;
     
-    JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable = 0)
+    JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope)
         : Base(vm, structure, scope)
     {
-        if (symbolTable)
-            m_symbolTable.set(vm, this, symbolTable);
     }
-
-    void finishCreation(VM& vm)
+    
+    JSSymbolTableObject(VM& vm, Structure* structure, JSScope* scope, SymbolTable* symbolTable)
+        : Base(vm, structure, scope)
     {
-        Base::finishCreation(vm);
-        if (!m_symbolTable)
-            m_symbolTable.set(vm, this, SymbolTable::create(vm));
+        ASSERT(symbolTable);
+        m_symbolTable.set(vm, this, symbolTable);
     }
 
     static void visitChildren(JSCell*, SlotVisitor&);
index f947d5b..0487790 100644 (file)
@@ -347,6 +347,14 @@ public:
         symbolTable->finishCreation(vm);
         return symbolTable;
     }
+    
+    static SymbolTable* createNameScopeTable(VM& vm, const Identifier& ident, unsigned attributes)
+    {
+        SymbolTable* result = create(vm);
+        result->add(ident.impl(), SymbolTableEntry(-1, attributes));
+        return result;
+    }
+    
     static const bool needsDestruction = true;
     static const bool hasImmortalStructure = true;
     static void destroy(JSCell*);