Changeset 102545 in webkit for trunk/Source/JavaScriptCore/runtime/Arguments.h
- Timestamp:
- Dec 11, 2011, 4:35:51 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/runtime/Arguments.h
r100224 r102545 40 40 WriteBarrier<JSActivation> activation; 41 41 42 unsigned numParameters;43 ptrdiff_t firstParameterIndex;44 42 unsigned numArguments; 45 43 … … 47 45 OwnArrayPtr<WriteBarrier<Unknown> > registerArray; 48 46 49 WriteBarrier<Unknown>* extraArguments;50 47 OwnArrayPtr<bool> deletedArguments; 51 WriteBarrier<Unknown> extraArgumentsFixedBuffer[4];52 48 53 49 WriteBarrier<JSFunction> callee; … … 56 52 bool overrodeCaller : 1; 57 53 bool isStrictMode : 1; 58 bool isInlineFrame : 1; // If true, all arguments are in the extraArguments buffer.59 54 }; 60 61 55 62 56 class Arguments : public JSNonFinalObject { … … 70 64 return arguments; 71 65 } 72 73 static Arguments* createAndTearOff(JSGlobalData& globalData, CallFrame* callFrame)74 {75 Arguments* arguments = new (allocateCell<Arguments>(globalData.heap)) Arguments(callFrame);76 arguments->finishCreationAndTearOff(callFrame);77 return arguments;78 }79 80 static Arguments* createNoParameters(JSGlobalData& globalData, CallFrame* callFrame)81 {82 Arguments* arguments = new (allocateCell<Arguments>(globalData.heap)) Arguments(callFrame, NoParameters);83 arguments->finishCreation(callFrame, NoParameters);84 return arguments;85 }86 66 87 // Use an enum because otherwise gcc insists on doing a memory88 // read.89 67 enum { MaxArguments = 0x10000 }; 90 68 … … 96 74 97 75 public: 98 virtual ~Arguments();99 100 76 static const ClassInfo s_info; 101 77 … … 111 87 } 112 88 113 void copyTo Registers(ExecState* exec, Register* buffer, uint32_t maxSize);114 void tearOff( JSGlobalData&);89 void copyToArguments(ExecState*, CallFrame*, uint32_t length); 90 void tearOff(CallFrame*); 115 91 bool isTornOff() const { return d->registerArray; } 116 92 void didTearOffActivation(JSGlobalData& globalData, JSActivation* activation) … … 130 106 static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; 131 107 132 void finishCreationButDontTearOff(CallFrame*);133 108 void finishCreation(CallFrame*); 134 void finishCreationAndTearOff(CallFrame*);135 void finishCreation(CallFrame*, NoParametersType);136 109 137 110 private: 138 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);139 111 static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier& propertyName, PropertySlot&); 140 112 static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&); … … 147 119 void createStrictModeCallerIfNecessary(ExecState*); 148 120 void createStrictModeCalleeIfNecessary(ExecState*); 121 122 WriteBarrier<Unknown>& argument(size_t); 149 123 150 124 void init(CallFrame*); … … 161 135 } 162 136 163 ALWAYS_INLINE void Arguments::getArgumentsData(CallFrame* callFrame, JSFunction*& function, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc)164 {165 function = asFunction(callFrame->callee());166 167 int numParameters = function->jsExecutable()->parameterCount();168 argc = callFrame->argumentCountIncludingThis();169 170 if (callFrame->isInlineCallFrame())171 ASSERT(argc == numParameters + 1);172 173 if (argc <= numParameters)174 argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters;175 else176 argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numParameters - argc;177 178 argc -= 1; // - 1 to skip "this"179 firstParameterIndex = -RegisterFile::CallFrameHeaderSize - numParameters;180 }181 182 137 inline Arguments::Arguments(CallFrame* callFrame) 183 138 : JSNonFinalObject(callFrame->globalData(), callFrame->lexicalGlobalObject()->argumentsStructure()) … … 191 146 { 192 147 } 193 194 inline void Arguments::finishCreationButDontTearOff(CallFrame* callFrame) 148 149 inline WriteBarrier<Unknown>& Arguments::argument(size_t i) 150 { 151 return d->registers[CallFrame::argumentOffset(i)]; 152 } 153 154 inline void Arguments::finishCreation(CallFrame* callFrame) 195 155 { 196 156 Base::finishCreation(callFrame->globalData()); 197 157 ASSERT(inherits(&s_info)); 198 158 199 JSFunction* callee; 200 ptrdiff_t firstParameterIndex; 201 Register* argv; 202 int numArguments; 203 getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments); 204 205 d->numParameters = callee->jsExecutable()->parameterCount(); 206 d->firstParameterIndex = firstParameterIndex; 207 d->numArguments = numArguments; 208 d->isInlineFrame = false; 209 159 JSFunction* callee = asFunction(callFrame->callee()); 160 d->numArguments = callFrame->argumentCount(); 210 161 d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers()); 211 212 WriteBarrier<Unknown>* extraArguments;213 if (d->numArguments <= d->numParameters)214 extraArguments = 0;215 else {216 unsigned numExtraArguments = d->numArguments - d->numParameters;217 if (numExtraArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(WriteBarrier<Unknown>))218 extraArguments = new WriteBarrier<Unknown>[numExtraArguments];219 else220 extraArguments = d->extraArgumentsFixedBuffer;221 for (unsigned i = 0; i < numExtraArguments; ++i)222 extraArguments[i].set(callFrame->globalData(), this, argv[d->numParameters + i].jsValue());223 }224 225 d->extraArguments = extraArguments;226 227 162 d->callee.set(callFrame->globalData(), this, callee); 228 163 d->overrodeLength = false; … … 230 165 d->overrodeCaller = false; 231 166 d->isStrictMode = callFrame->codeBlock()->isStrictMode(); 232 }233 167 234 inline void Arguments::finishCreation(CallFrame* callFrame) 235 { 236 ASSERT(!callFrame->isInlineCallFrame()); 237 finishCreationButDontTearOff(callFrame); 238 if (d->isStrictMode) 239 tearOff(callFrame->globalData()); 240 } 241 242 inline void Arguments::finishCreationAndTearOff(CallFrame* callFrame) 243 { 244 Base::finishCreation(callFrame->globalData()); 245 ASSERT(inherits(&s_info)); 246 247 JSFunction* callee; 248 249 ptrdiff_t firstParameterIndex; 250 Register* argv; 251 int numArguments; 252 getArgumentsData(callFrame, callee, firstParameterIndex, argv, numArguments); 253 254 d->numParameters = callee->jsExecutable()->parameterCount(); 255 d->firstParameterIndex = firstParameterIndex; 256 d->numArguments = numArguments; 257 258 if (d->numParameters) { 259 int registerOffset = d->numParameters + RegisterFile::CallFrameHeaderSize; 260 size_t registerArraySize = d->numParameters; 261 262 OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]); 263 if (callFrame->isInlineCallFrame()) { 264 InlineCallFrame* inlineCallFrame = callFrame->inlineCallFrame(); 265 for (size_t i = 0; i < registerArraySize; ++i) { 266 ValueRecovery& recovery = inlineCallFrame->arguments[i + 1]; 267 // In the future we'll support displaced recoveries (indicating that the 268 // argument was flushed to a different location), but for now we don't do 269 // that so this code will fail if that were to happen. On the other hand, 270 // it's much less likely that we'll support in-register recoveries since 271 // this code does not (easily) have access to registers. 272 JSValue value; 273 Register* location = callFrame->registers() + i - registerOffset; 274 switch (recovery.technique()) { 275 case AlreadyInRegisterFile: 276 value = location->jsValue(); 277 break; 278 case AlreadyInRegisterFileAsUnboxedInt32: 279 value = jsNumber(location->unboxedInt32()); 280 break; 281 case AlreadyInRegisterFileAsUnboxedCell: 282 value = location->unboxedCell(); 283 break; 284 case AlreadyInRegisterFileAsUnboxedBoolean: 285 value = jsBoolean(location->unboxedBoolean()); 286 break; 287 case Constant: 288 value = recovery.constant(); 289 break; 290 default: 291 ASSERT_NOT_REACHED(); 292 break; 293 } 294 registerArray[i].set(callFrame->globalData(), this, value); 295 } 296 } else { 297 for (size_t i = 0; i < registerArraySize; ++i) 298 registerArray[i].set(callFrame->globalData(), this, callFrame->registers()[i - registerOffset].jsValue()); 299 } 300 d->registers = registerArray.get() + d->numParameters + RegisterFile::CallFrameHeaderSize; 301 d->registerArray = registerArray.release(); 302 } 303 304 WriteBarrier<Unknown>* extraArguments; 305 if (callFrame->isInlineCallFrame()) 306 ASSERT(d->numArguments == d->numParameters); 307 if (d->numArguments <= d->numParameters) 308 extraArguments = 0; 309 else { 310 unsigned numExtraArguments = d->numArguments - d->numParameters; 311 if (numExtraArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(WriteBarrier<Unknown>)) 312 extraArguments = new WriteBarrier<Unknown>[numExtraArguments]; 313 else 314 extraArguments = d->extraArgumentsFixedBuffer; 315 for (unsigned i = 0; i < numExtraArguments; ++i) 316 extraArguments[i].set(callFrame->globalData(), this, argv[d->numParameters + i].jsValue()); 317 } 318 319 d->extraArguments = extraArguments; 320 321 d->callee.set(callFrame->globalData(), this, callee); 322 d->overrodeLength = false; 323 d->overrodeCallee = false; 324 d->overrodeCaller = false; 325 d->isInlineFrame = callFrame->isInlineCallFrame(); 326 d->isStrictMode = callFrame->codeBlock()->isStrictMode(); 327 } 328 329 inline void Arguments::finishCreation(CallFrame* callFrame, NoParametersType) 330 { 331 ASSERT(!callFrame->isInlineCallFrame()); 332 Base::finishCreation(callFrame->globalData()); 333 ASSERT(inherits(&s_info)); 334 ASSERT(!asFunction(callFrame->callee())->jsExecutable()->parameterCount()); 335 336 unsigned numArguments = callFrame->argumentCount(); 337 338 d->numParameters = 0; 339 d->numArguments = numArguments; 340 d->isInlineFrame = false; 341 342 WriteBarrier<Unknown>* extraArguments; 343 if (numArguments > sizeof(d->extraArgumentsFixedBuffer) / sizeof(Register)) 344 extraArguments = new WriteBarrier<Unknown>[numArguments]; 345 else 346 extraArguments = d->extraArgumentsFixedBuffer; 347 348 Register* argv = callFrame->registers() - RegisterFile::CallFrameHeaderSize - numArguments - 1; 349 for (unsigned i = 0; i < numArguments; ++i) 350 extraArguments[i].set(callFrame->globalData(), this, argv[i].jsValue()); 351 352 d->extraArguments = extraArguments; 353 354 d->callee.set(callFrame->globalData(), this, asFunction(callFrame->callee())); 355 d->overrodeLength = false; 356 d->overrodeCallee = false; 357 d->overrodeCaller = false; 358 d->isStrictMode = callFrame->codeBlock()->isStrictMode(); 359 if (d->isStrictMode) 360 tearOff(callFrame->globalData()); 361 } 362 363 inline void Arguments::tearOff(JSGlobalData& globalData) 364 { 365 ASSERT(!isTornOff()); 366 367 if (!d->numParameters) 368 return; 369 370 int registerOffset = d->numParameters + RegisterFile::CallFrameHeaderSize; 371 size_t registerArraySize = d->numParameters; 372 373 OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]); 374 for (size_t i = 0; i < registerArraySize; i++) 375 registerArray[i].set(globalData, this, d->registers[i - registerOffset].get()); 376 d->registers = registerArray.get() + registerOffset; 377 d->registerArray = registerArray.release(); 168 // The bytecode generator omits op_tear_off_activation in cases of no 169 // declared parameters, so we need to tear off immediately. 170 if (d->isStrictMode || !callee->jsExecutable()->parameterCount()) 171 tearOff(callFrame); 378 172 } 379 173
Note:
See TracChangeset
for help on using the changeset viewer.