Changeset 128832 in webkit for trunk/Source/JavaScriptCore/runtime/Arguments.h
- Timestamp:
- Sep 17, 2012, 6:15:04 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/Arguments.h
r128813 r128832 35 35 namespace JSC { 36 36 37 struct ArgumentsData {38 WTF_MAKE_NONCOPYABLE(ArgumentsData); WTF_MAKE_FAST_ALLOCATED;39 public:40 ArgumentsData() { }41 WriteBarrier<JSActivation> activation;42 43 unsigned numArguments;44 45 // We make these full byte booleans to make them easy to test from the JIT,46 // and because even if they were single-bit booleans we still wouldn't save47 // any space.48 bool overrodeLength;49 bool overrodeCallee;50 bool overrodeCaller;51 bool isStrictMode;52 53 WriteBarrierBase<Unknown>* registers;54 OwnArrayPtr<WriteBarrier<Unknown> > registerArray;55 56 OwnArrayPtr<bool> deletedArguments;57 58 WriteBarrier<JSFunction> callee;59 };60 61 37 class Arguments : public JSDestructibleObject { 38 friend class JIT; 39 friend class DFG::SpeculativeJIT; 62 40 public: 63 41 typedef JSDestructibleObject Base; … … 96 74 uint32_t length(ExecState* exec) const 97 75 { 98 if (UNLIKELY( d->overrodeLength))76 if (UNLIKELY(m_overrodeLength)) 99 77 return get(exec, exec->propertyNames().length).toUInt32(exec); 100 return d->numArguments;78 return m_numArguments; 101 79 } 102 80 … … 104 82 void tearOff(CallFrame*); 105 83 void tearOff(CallFrame*, InlineCallFrame*); 106 bool isTornOff() const { return d->registerArray; } 107 void didTearOffActivation(JSGlobalData& globalData, JSActivation* activation) 108 { 109 if (isTornOff()) 110 return; 111 d->activation.set(globalData, this, activation); 112 d->registers = &activation->registerAt(0); 113 } 84 bool isTornOff() const { return m_registerArray; } 85 void didTearOffActivation(ExecState*, JSActivation*); 114 86 115 87 static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) … … 118 90 } 119 91 120 static ptrdiff_t offsetOfData() { return OBJECT_OFFSETOF(Arguments, d); }121 122 92 protected: 123 93 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; … … 140 110 void createStrictModeCalleeIfNecessary(ExecState*); 141 111 112 bool isArgument(size_t); 113 bool trySetArgument(JSGlobalData&, size_t argument, JSValue); 114 JSValue tryGetArgument(size_t argument); 115 bool isDeletedArgument(size_t); 116 bool tryDeleteArgument(size_t); 142 117 WriteBarrierBase<Unknown>& argument(size_t); 118 void allocateSlowArguments(); 143 119 144 120 void init(CallFrame*); 145 121 146 OwnPtr<ArgumentsData> d; 122 WriteBarrier<JSActivation> m_activation; 123 124 unsigned m_numArguments; 125 126 // We make these full byte booleans to make them easy to test from the JIT, 127 // and because even if they were single-bit booleans we still wouldn't save 128 // any space. 129 bool m_overrodeLength; 130 bool m_overrodeCallee; 131 bool m_overrodeCaller; 132 bool m_isStrictMode; 133 134 WriteBarrierBase<Unknown>* m_registers; 135 OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; 136 137 OwnArrayPtr<SlowArgument> m_slowArguments; 138 139 WriteBarrier<JSFunction> m_callee; 147 140 }; 148 141 … … 157 150 inline Arguments::Arguments(CallFrame* callFrame) 158 151 : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) 159 , d(adoptPtr(new ArgumentsData))160 152 { 161 153 } … … 163 155 inline Arguments::Arguments(CallFrame* callFrame, NoParametersType) 164 156 : JSDestructibleObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) 165 , d(adoptPtr(new ArgumentsData)) 166 { 167 } 168 169 inline WriteBarrierBase<Unknown>& Arguments::argument(size_t i) 170 { 171 return d->registers[CallFrame::argumentOffset(i)]; 157 { 158 } 159 160 inline void Arguments::allocateSlowArguments() 161 { 162 if (m_slowArguments) 163 return; 164 m_slowArguments = adoptArrayPtr(new SlowArgument[m_numArguments]); 165 } 166 167 inline bool Arguments::tryDeleteArgument(size_t argument) 168 { 169 if (!isArgument(argument)) 170 return false; 171 allocateSlowArguments(); 172 m_slowArguments[argument].status = SlowArgument::Deleted; 173 return true; 174 } 175 176 inline bool Arguments::trySetArgument(JSGlobalData& globalData, size_t argument, JSValue value) 177 { 178 if (!isArgument(argument)) 179 return false; 180 this->argument(argument).set(globalData, this, value); 181 return true; 182 } 183 184 inline JSValue Arguments::tryGetArgument(size_t argument) 185 { 186 if (!isArgument(argument)) 187 return JSValue(); 188 return this->argument(argument).get(); 189 } 190 191 inline bool Arguments::isDeletedArgument(size_t argument) 192 { 193 if (argument >= m_numArguments) 194 return false; 195 if (!m_slowArguments) 196 return false; 197 if (m_slowArguments[argument].status != SlowArgument::Deleted) 198 return false; 199 return true; 200 } 201 202 inline bool Arguments::isArgument(size_t argument) 203 { 204 if (argument >= m_numArguments) 205 return false; 206 if (m_slowArguments && m_slowArguments[argument].status == SlowArgument::Deleted) 207 return false; 208 return true; 209 } 210 211 inline WriteBarrierBase<Unknown>& Arguments::argument(size_t argument) 212 { 213 ASSERT(isArgument(argument)); 214 if (!m_slowArguments || m_slowArguments[argument].status == SlowArgument::Normal) 215 return m_registers[CallFrame::argumentOffset(argument)]; 216 217 ASSERT(m_slowArguments[argument].status == SlowArgument::Captured); 218 if (!m_activation) 219 return m_registers[m_slowArguments[argument].indexIfCaptured]; 220 221 return m_activation->registerAt(m_slowArguments[argument].indexIfCaptured); 172 222 } 173 223 … … 178 228 179 229 JSFunction* callee = jsCast<JSFunction*>(callFrame->callee()); 180 d->numArguments = callFrame->argumentCount();181 d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers());182 d->callee.set(callFrame->globalData(), this, callee);183 d->overrodeLength = false;184 d->overrodeCallee = false;185 d->overrodeCaller = false;186 d->isStrictMode = callFrame->codeBlock()->isStrictMode();230 m_numArguments = callFrame->argumentCount(); 231 m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()); 232 m_callee.set(callFrame->globalData(), this, callee); 233 m_overrodeLength = false; 234 m_overrodeCallee = false; 235 m_overrodeCaller = false; 236 m_isStrictMode = callFrame->codeBlock()->isStrictMode(); 187 237 188 238 // The bytecode generator omits op_tear_off_activation in cases of no 189 239 // declared parameters, so we need to tear off immediately. 190 if ( d->isStrictMode || !callee->jsExecutable()->parameterCount())240 if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) 191 241 tearOff(callFrame); 192 242 } … … 198 248 199 249 JSFunction* callee = inlineCallFrame->callee.get(); 200 d->numArguments = inlineCallFrame->arguments.size() - 1;201 d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset;202 d->callee.set(callFrame->globalData(), this, callee);203 d->overrodeLength = false;204 d->overrodeCallee = false;205 d->overrodeCaller = false;206 d->isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode();250 m_numArguments = inlineCallFrame->arguments.size() - 1; 251 m_registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset; 252 m_callee.set(callFrame->globalData(), this, callee); 253 m_overrodeLength = false; 254 m_overrodeCallee = false; 255 m_overrodeCaller = false; 256 m_isStrictMode = jsCast<FunctionExecutable*>(inlineCallFrame->executable.get())->isStrictMode(); 207 257 208 258 // The bytecode generator omits op_tear_off_activation in cases of no 209 259 // declared parameters, so we need to tear off immediately. 210 if ( d->isStrictMode || !callee->jsExecutable()->parameterCount())260 if (m_isStrictMode || !callee->jsExecutable()->parameterCount()) 211 261 tearOff(callFrame, inlineCallFrame); 212 262 }
Note:
See TracChangeset
for help on using the changeset viewer.