Changeset 188242 in webkit for trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h
- Timestamp:
- Aug 10, 2015, 6:26:30 PM (10 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/bytecode/ExecutableInfo.h
r188219 r188242 24 24 */ 25 25 26 #ifndef UnlinkedCodeBlock_h27 #define UnlinkedCodeBlock_h26 #ifndef ExecutableInfo_h 27 #define ExecutableInfo_h 28 28 29 #include "BytecodeConventions.h"30 #include "CodeSpecializationKind.h"31 #include "CodeType.h"32 #include "ConstructAbility.h"33 #include "ExpressionRangeInfo.h"34 #include "HandlerInfo.h"35 #include "Identifier.h"36 #include "JSCell.h"37 #include "JSString.h"38 29 #include "ParserModes.h" 39 #include "RegExp.h"40 #include "SpecialPointer.h"41 #include "SymbolTable.h"42 #include "VariableEnvironment.h"43 #include "VirtualRegister.h"44 45 #include <wtf/RefCountedArray.h>46 #include <wtf/Vector.h>47 30 48 31 namespace JSC { 49 50 class Debugger;51 class FunctionMetadataNode;52 class FunctionExecutable;53 class JSScope;54 class ParserError;55 class ScriptExecutable;56 class SourceCode;57 class SourceProvider;58 class SymbolTable;59 class UnlinkedCodeBlock;60 class UnlinkedFunctionCodeBlock;61 class UnlinkedInstructionStream;62 63 typedef unsigned UnlinkedValueProfile;64 typedef unsigned UnlinkedArrayProfile;65 typedef unsigned UnlinkedArrayAllocationProfile;66 typedef unsigned UnlinkedObjectAllocationProfile;67 typedef unsigned UnlinkedLLIntCallLinkInfo;68 32 69 33 struct ExecutableInfo { … … 95 59 }; 96 60 97 enum UnlinkedFunctionKind { 98 UnlinkedNormalFunction, 99 UnlinkedBuiltinFunction, 100 }; 61 } // namespace JSC 101 62 102 class UnlinkedFunctionExecutable final : public JSCell { 103 public: 104 friend class BuiltinExecutables; 105 friend class CodeCache; 106 friend class VM; 107 108 typedef JSCell Base; 109 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 110 111 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionMetadataNode* node, UnlinkedFunctionKind unlinkedFunctionKind, ConstructAbility constructAbility, VariableEnvironment& parentScopeTDZVariables, RefPtr<SourceProvider>&& sourceOverride = nullptr) 112 { 113 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) 114 UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, WTF::move(sourceOverride), node, unlinkedFunctionKind, constructAbility, parentScopeTDZVariables); 115 instance->finishCreation(*vm); 116 return instance; 117 } 118 119 const Identifier& name() const { return m_name; } 120 const Identifier& inferredName() const { return m_inferredName; } 121 JSString* nameValue() const { return m_nameValue.get(); } 122 unsigned parameterCount() const { return m_parameterCount; }; 123 FunctionParseMode parseMode() const { return m_parseMode; }; 124 bool isInStrictContext() const { return m_isInStrictContext; } 125 FunctionMode functionMode() const { return static_cast<FunctionMode>(m_functionMode); } 126 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } 127 128 unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; } 129 unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; } 130 unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; } 131 unsigned startOffset() const { return m_startOffset; } 132 unsigned sourceLength() { return m_sourceLength; } 133 unsigned parametersStartOffset() const { return m_parametersStartOffset; } 134 unsigned typeProfilingStartOffset() const { return m_typeProfilingStartOffset; } 135 unsigned typeProfilingEndOffset() const { return m_typeProfilingEndOffset; } 136 137 UnlinkedFunctionCodeBlock* codeBlockFor( 138 VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, 139 ParserError&); 140 141 static UnlinkedFunctionExecutable* fromGlobalCode( 142 const Identifier&, ExecState&, const SourceCode&, JSObject*& exception, 143 int overrideLineNumber); 144 145 FunctionExecutable* link(VM&, const SourceCode&, int overrideLineNumber = -1); 146 147 void clearCodeForRecompilation() 148 { 149 m_codeBlockForCall.clear(); 150 m_codeBlockForConstruct.clear(); 151 } 152 153 void recordParse(CodeFeatures features, bool hasCapturedVariables) 154 { 155 m_features = features; 156 m_hasCapturedVariables = hasCapturedVariables; 157 } 158 159 CodeFeatures features() const { return m_features; } 160 bool hasCapturedVariables() const { return m_hasCapturedVariables; } 161 162 static const bool needsDestruction = true; 163 static void destroy(JSCell*); 164 165 bool isBuiltinFunction() const { return m_isBuiltinFunction; } 166 ConstructAbility constructAbility() const { return static_cast<ConstructAbility>(m_constructAbility); } 167 bool isClassConstructorFunction() const { return constructorKind() != ConstructorKind::None; } 168 const VariableEnvironment* parentScopeTDZVariables() const { return &m_parentScopeTDZVariables; } 169 170 private: 171 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, RefPtr<SourceProvider>&& sourceOverride, FunctionMetadataNode*, UnlinkedFunctionKind, ConstructAbility, VariableEnvironment&); 172 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall; 173 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct; 174 175 Identifier m_name; 176 Identifier m_inferredName; 177 WriteBarrier<JSString> m_nameValue; 178 RefPtr<SourceProvider> m_sourceOverride; 179 VariableEnvironment m_parentScopeTDZVariables; 180 unsigned m_firstLineOffset; 181 unsigned m_lineCount; 182 unsigned m_unlinkedFunctionNameStart; 183 unsigned m_unlinkedBodyStartColumn; 184 unsigned m_unlinkedBodyEndColumn; 185 unsigned m_startOffset; 186 unsigned m_sourceLength; 187 unsigned m_parametersStartOffset; 188 unsigned m_typeProfilingStartOffset; 189 unsigned m_typeProfilingEndOffset; 190 unsigned m_parameterCount; 191 FunctionParseMode m_parseMode; 192 193 CodeFeatures m_features; 194 195 unsigned m_isInStrictContext : 1; 196 unsigned m_hasCapturedVariables : 1; 197 unsigned m_isBuiltinFunction : 1; 198 unsigned m_constructAbility: 1; 199 unsigned m_constructorKind : 2; 200 unsigned m_functionMode : 1; // FunctionMode 201 202 protected: 203 void finishCreation(VM& vm) 204 { 205 Base::finishCreation(vm); 206 m_nameValue.set(vm, this, jsString(&vm, name().string())); 207 } 208 209 static void visitChildren(JSCell*, SlotVisitor&); 210 211 public: 212 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 213 { 214 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info()); 215 } 216 217 DECLARE_EXPORT_INFO; 218 }; 219 220 struct UnlinkedStringJumpTable { 221 typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable; 222 StringOffsetTable offsetTable; 223 224 inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset) 225 { 226 StringOffsetTable::const_iterator end = offsetTable.end(); 227 StringOffsetTable::const_iterator loc = offsetTable.find(value); 228 if (loc == end) 229 return defaultOffset; 230 return loc->value; 231 } 232 233 }; 234 235 struct UnlinkedSimpleJumpTable { 236 Vector<int32_t> branchOffsets; 237 int32_t min; 238 239 int32_t offsetForValue(int32_t value, int32_t defaultOffset); 240 void add(int32_t key, int32_t offset) 241 { 242 if (!branchOffsets[key]) 243 branchOffsets[key] = offset; 244 } 245 }; 246 247 struct UnlinkedInstruction { 248 UnlinkedInstruction() { u.operand = 0; } 249 UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; } 250 UnlinkedInstruction(int operand) { u.operand = operand; } 251 union { 252 OpcodeID opcode; 253 int32_t operand; 254 unsigned index; 255 } u; 256 }; 257 258 class UnlinkedCodeBlock : public JSCell { 259 public: 260 typedef JSCell Base; 261 static const unsigned StructureFlags = Base::StructureFlags; 262 263 static const bool needsDestruction = true; 264 265 enum { CallFunction, ApplyFunction }; 266 267 bool isConstructor() const { return m_isConstructor; } 268 bool isStrictMode() const { return m_isStrictMode; } 269 bool usesEval() const { return m_usesEval; } 270 271 bool needsFullScopeChain() const { return m_needsFullScopeChain; } 272 273 void addExpressionInfo(unsigned instructionOffset, int divot, 274 int startOffset, int endOffset, unsigned line, unsigned column); 275 276 void addTypeProfilerExpressionInfo(unsigned instructionOffset, unsigned startDivot, unsigned endDivot); 277 278 bool hasExpressionInfo() { return m_expressionInfo.size(); } 279 280 // Special registers 281 void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; } 282 void setScopeRegister(VirtualRegister scopeRegister) { m_scopeRegister = scopeRegister; } 283 void setActivationRegister(VirtualRegister activationRegister) { m_lexicalEnvironmentRegister = activationRegister; } 284 285 bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); } 286 void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; } 287 VirtualRegister globalObjectRegister() const { return m_globalObjectRegister; } 288 289 // Parameter information 290 void setNumParameters(int newValue) { m_numParameters = newValue; } 291 void addParameter() { m_numParameters++; } 292 unsigned numParameters() const { return m_numParameters; } 293 294 unsigned addRegExp(RegExp* r) 295 { 296 createRareDataIfNecessary(); 297 unsigned size = m_rareData->m_regexps.size(); 298 m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r)); 299 return size; 300 } 301 unsigned numberOfRegExps() const 302 { 303 if (!m_rareData) 304 return 0; 305 return m_rareData->m_regexps.size(); 306 } 307 RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); } 308 309 // Constant Pools 310 311 size_t numberOfIdentifiers() const { return m_identifiers.size(); } 312 void addIdentifier(const Identifier& i) { return m_identifiers.append(i); } 313 const Identifier& identifier(int index) const { return m_identifiers[index]; } 314 const Vector<Identifier>& identifiers() const { return m_identifiers; } 315 316 unsigned addConstant(JSValue v, SourceCodeRepresentation sourceCodeRepresentation = SourceCodeRepresentation::Other) 317 { 318 unsigned result = m_constantRegisters.size(); 319 m_constantRegisters.append(WriteBarrier<Unknown>()); 320 m_constantRegisters.last().set(*m_vm, this, v); 321 m_constantsSourceCodeRepresentation.append(sourceCodeRepresentation); 322 return result; 323 } 324 unsigned addConstant(LinkTimeConstant type) 325 { 326 unsigned result = m_constantRegisters.size(); 327 ASSERT(result); 328 unsigned index = static_cast<unsigned>(type); 329 ASSERT(index < LinkTimeConstantCount); 330 m_linkTimeConstants[index] = result; 331 m_constantRegisters.append(WriteBarrier<Unknown>()); 332 m_constantsSourceCodeRepresentation.append(SourceCodeRepresentation::Other); 333 return result; 334 } 335 unsigned registerIndexForLinkTimeConstant(LinkTimeConstant type) 336 { 337 unsigned index = static_cast<unsigned>(type); 338 ASSERT(index < LinkTimeConstantCount); 339 return m_linkTimeConstants[index]; 340 } 341 const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; } 342 const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; } 343 ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; } 344 const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation() { return m_constantsSourceCodeRepresentation; } 345 346 // Jumps 347 size_t numberOfJumpTargets() const { return m_jumpTargets.size(); } 348 void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); } 349 unsigned jumpTarget(int index) const { return m_jumpTargets[index]; } 350 unsigned lastJumpTarget() const { return m_jumpTargets.last(); } 351 352 bool isBuiltinFunction() const { return m_isBuiltinFunction; } 353 354 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); } 355 356 void shrinkToFit() 357 { 358 m_jumpTargets.shrinkToFit(); 359 m_identifiers.shrinkToFit(); 360 m_constantRegisters.shrinkToFit(); 361 m_constantsSourceCodeRepresentation.shrinkToFit(); 362 m_functionDecls.shrinkToFit(); 363 m_functionExprs.shrinkToFit(); 364 m_propertyAccessInstructions.shrinkToFit(); 365 m_expressionInfo.shrinkToFit(); 366 367 #if ENABLE(BYTECODE_COMMENTS) 368 m_bytecodeComments.shrinkToFit(); 369 #endif 370 if (m_rareData) { 371 m_rareData->m_exceptionHandlers.shrinkToFit(); 372 m_rareData->m_regexps.shrinkToFit(); 373 m_rareData->m_constantBuffers.shrinkToFit(); 374 m_rareData->m_switchJumpTables.shrinkToFit(); 375 m_rareData->m_stringSwitchJumpTables.shrinkToFit(); 376 m_rareData->m_expressionInfoFatPositions.shrinkToFit(); 377 } 378 } 379 380 void setInstructions(std::unique_ptr<UnlinkedInstructionStream>); 381 const UnlinkedInstructionStream& instructions() const; 382 383 int m_numVars; 384 int m_numCapturedVars; 385 int m_numCalleeRegisters; 386 387 // Jump Tables 388 389 size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; } 390 UnlinkedSimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); } 391 UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; } 392 393 size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; } 394 UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); } 395 UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; } 396 397 unsigned addFunctionDecl(UnlinkedFunctionExecutable* n) 398 { 399 unsigned size = m_functionDecls.size(); 400 m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>()); 401 m_functionDecls.last().set(*m_vm, this, n); 402 return size; 403 } 404 UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); } 405 size_t numberOfFunctionDecls() { return m_functionDecls.size(); } 406 unsigned addFunctionExpr(UnlinkedFunctionExecutable* n) 407 { 408 unsigned size = m_functionExprs.size(); 409 m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>()); 410 m_functionExprs.last().set(*m_vm, this, n); 411 return size; 412 } 413 UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); } 414 size_t numberOfFunctionExprs() { return m_functionExprs.size(); } 415 416 // Exception handling support 417 size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; } 418 void addExceptionHandler(const UnlinkedHandlerInfo& handler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(handler); } 419 UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; } 420 421 VM* vm() const { return m_vm; } 422 423 UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; } 424 unsigned numberOfArrayProfiles() { return m_arrayProfileCount; } 425 UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; } 426 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; } 427 UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; } 428 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; } 429 UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; } 430 unsigned numberOfValueProfiles() { return m_valueProfileCount; } 431 432 UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; } 433 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; } 434 435 CodeType codeType() const { return m_codeType; } 436 437 VirtualRegister thisRegister() const { return m_thisRegister; } 438 VirtualRegister scopeRegister() const { return m_scopeRegister; } 439 VirtualRegister activationRegister() const { return m_lexicalEnvironmentRegister; } 440 bool hasActivationRegister() const { return m_lexicalEnvironmentRegister.isValid(); } 441 442 void addPropertyAccessInstruction(unsigned propertyAccessInstruction) 443 { 444 m_propertyAccessInstructions.append(propertyAccessInstruction); 445 } 446 447 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); } 448 const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; } 449 450 typedef Vector<JSValue> ConstantBuffer; 451 452 size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); } 453 unsigned addConstantBuffer(unsigned length) 454 { 455 createRareDataIfNecessary(); 456 unsigned size = m_rareData->m_constantBuffers.size(); 457 m_rareData->m_constantBuffers.append(Vector<JSValue>(length)); 458 return size; 459 } 460 461 const ConstantBuffer& constantBuffer(unsigned index) const 462 { 463 ASSERT(m_rareData); 464 return m_rareData->m_constantBuffers[index]; 465 } 466 467 ConstantBuffer& constantBuffer(unsigned index) 468 { 469 ASSERT(m_rareData); 470 return m_rareData->m_constantBuffers[index]; 471 } 472 473 bool hasRareData() const { return m_rareData.get(); } 474 475 int lineNumberForBytecodeOffset(unsigned bytecodeOffset); 476 477 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot, 478 int& startOffset, int& endOffset, unsigned& line, unsigned& column); 479 480 bool typeProfilerExpressionInfoForBytecodeOffset(unsigned bytecodeOffset, unsigned& startDivot, unsigned& endDivot); 481 482 void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn) 483 { 484 m_features = features; 485 m_hasCapturedVariables = hasCapturedVariables; 486 m_firstLine = firstLine; 487 m_lineCount = lineCount; 488 // For the UnlinkedCodeBlock, startColumn is always 0. 489 m_endColumn = endColumn; 490 } 491 492 CodeFeatures codeFeatures() const { return m_features; } 493 bool hasCapturedVariables() const { return m_hasCapturedVariables; } 494 unsigned firstLine() const { return m_firstLine; } 495 unsigned lineCount() const { return m_lineCount; } 496 ALWAYS_INLINE unsigned startColumn() const { return 0; } 497 unsigned endColumn() const { return m_endColumn; } 498 499 void addOpProfileControlFlowBytecodeOffset(size_t offset) { m_opProfileControlFlowBytecodeOffsets.append(offset); } 500 const Vector<size_t>& opProfileControlFlowBytecodeOffsets() const { return m_opProfileControlFlowBytecodeOffsets; } 501 502 void dumpExpressionRangeInfo(); // For debugging purpose only. 503 504 protected: 505 UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&); 506 ~UnlinkedCodeBlock(); 507 508 void finishCreation(VM& vm) 509 { 510 Base::finishCreation(vm); 511 if (codeType() == GlobalCode) 512 return; 513 m_symbolTable.set(vm, this, SymbolTable::create(vm)); 514 } 515 516 private: 517 518 void createRareDataIfNecessary() 519 { 520 if (!m_rareData) 521 m_rareData = std::make_unique<RareData>(); 522 } 523 524 void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column); 525 526 std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions; 527 528 int m_numParameters; 529 VM* m_vm; 530 531 VirtualRegister m_thisRegister; 532 VirtualRegister m_scopeRegister; 533 VirtualRegister m_lexicalEnvironmentRegister; 534 VirtualRegister m_globalObjectRegister; 535 536 unsigned m_needsFullScopeChain : 1; 537 unsigned m_usesEval : 1; 538 unsigned m_isStrictMode : 1; 539 unsigned m_isConstructor : 1; 540 unsigned m_hasCapturedVariables : 1; 541 unsigned m_isBuiltinFunction : 1; 542 unsigned m_constructorKind : 2; 543 544 unsigned m_firstLine; 545 unsigned m_lineCount; 546 unsigned m_endColumn; 547 548 CodeFeatures m_features; 549 CodeType m_codeType; 550 551 Vector<unsigned> m_jumpTargets; 552 553 // Constant Pools 554 Vector<Identifier> m_identifiers; 555 Vector<WriteBarrier<Unknown>> m_constantRegisters; 556 Vector<SourceCodeRepresentation> m_constantsSourceCodeRepresentation; 557 std::array<unsigned, LinkTimeConstantCount> m_linkTimeConstants; 558 typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector; 559 FunctionExpressionVector m_functionDecls; 560 FunctionExpressionVector m_functionExprs; 561 562 WriteBarrier<SymbolTable> m_symbolTable; 563 564 Vector<unsigned> m_propertyAccessInstructions; 565 566 #if ENABLE(BYTECODE_COMMENTS) 567 Vector<Comment> m_bytecodeComments; 568 size_t m_bytecodeCommentIterator; 569 #endif 570 571 unsigned m_arrayProfileCount; 572 unsigned m_arrayAllocationProfileCount; 573 unsigned m_objectAllocationProfileCount; 574 unsigned m_valueProfileCount; 575 unsigned m_llintCallLinkInfoCount; 576 577 public: 578 struct RareData { 579 WTF_MAKE_FAST_ALLOCATED; 580 public: 581 Vector<UnlinkedHandlerInfo> m_exceptionHandlers; 582 583 // Rare Constants 584 Vector<WriteBarrier<RegExp>> m_regexps; 585 586 // Buffers used for large array literals 587 Vector<ConstantBuffer> m_constantBuffers; 588 589 // Jump Tables 590 Vector<UnlinkedSimpleJumpTable> m_switchJumpTables; 591 Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables; 592 593 Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions; 594 }; 595 596 private: 597 std::unique_ptr<RareData> m_rareData; 598 Vector<ExpressionRangeInfo> m_expressionInfo; 599 struct TypeProfilerExpressionRange { 600 unsigned m_startDivot; 601 unsigned m_endDivot; 602 }; 603 HashMap<unsigned, TypeProfilerExpressionRange> m_typeProfilerInfoMap; 604 Vector<size_t> m_opProfileControlFlowBytecodeOffsets; 605 606 protected: 607 static void visitChildren(JSCell*, SlotVisitor&); 608 609 public: 610 DECLARE_INFO; 611 }; 612 613 class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock { 614 public: 615 typedef UnlinkedCodeBlock Base; 616 617 protected: 618 UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info) 619 : Base(vm, structure, codeType, info) 620 { 621 } 622 623 DECLARE_INFO; 624 }; 625 626 class UnlinkedProgramCodeBlock final : public UnlinkedGlobalCodeBlock { 627 private: 628 friend class CodeCache; 629 static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info) 630 { 631 UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info); 632 instance->finishCreation(*vm); 633 return instance; 634 } 635 636 public: 637 typedef UnlinkedGlobalCodeBlock Base; 638 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 639 640 static void destroy(JSCell*); 641 642 void setVariableDeclarations(const VariableEnvironment& environment) { m_varDeclarations = environment; } 643 const VariableEnvironment& variableDeclarations() const { return m_varDeclarations; } 644 645 static void visitChildren(JSCell*, SlotVisitor&); 646 647 private: 648 UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) 649 : Base(vm, structure, GlobalCode, info) 650 { 651 } 652 653 VariableEnvironment m_varDeclarations; 654 655 public: 656 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 657 { 658 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info()); 659 } 660 661 DECLARE_INFO; 662 }; 663 664 class UnlinkedEvalCodeBlock final : public UnlinkedGlobalCodeBlock { 665 private: 666 friend class CodeCache; 667 668 static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info) 669 { 670 UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info); 671 instance->finishCreation(*vm); 672 return instance; 673 } 674 675 public: 676 typedef UnlinkedGlobalCodeBlock Base; 677 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 678 679 static void destroy(JSCell*); 680 681 const Identifier& variable(unsigned index) { return m_variables[index]; } 682 unsigned numVariables() { return m_variables.size(); } 683 void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables) 684 { 685 ASSERT(m_variables.isEmpty()); 686 m_variables.swap(variables); 687 } 688 689 private: 690 UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info) 691 : Base(vm, structure, EvalCode, info) 692 { 693 } 694 695 Vector<Identifier, 0, UnsafeVectorOverflow> m_variables; 696 697 public: 698 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 699 { 700 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info()); 701 } 702 703 DECLARE_INFO; 704 }; 705 706 class UnlinkedFunctionCodeBlock final : public UnlinkedCodeBlock { 707 public: 708 typedef UnlinkedCodeBlock Base; 709 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 710 711 static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info) 712 { 713 UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info); 714 instance->finishCreation(*vm); 715 return instance; 716 } 717 718 static void destroy(JSCell*); 719 720 private: 721 UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info) 722 : Base(vm, structure, codeType, info) 723 { 724 } 725 726 public: 727 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto) 728 { 729 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info()); 730 } 731 732 DECLARE_INFO; 733 }; 734 735 } 736 737 #endif // UnlinkedCodeBlock_h 63 #endif // ExecutableInfo_h
Note:
See TracChangeset
for help on using the changeset viewer.