| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 EAGER_ARGUMENTS_ALLOCATION, | 287 EAGER_ARGUMENTS_ALLOCATION, |
| 288 LAZY_ARGUMENTS_ALLOCATION | 288 LAZY_ARGUMENTS_ALLOCATION |
| 289 }; | 289 }; |
| 290 | 290 |
| 291 | 291 |
| 292 // ------------------------------------------------------------------------- | 292 // ------------------------------------------------------------------------- |
| 293 // CodeGenerator | 293 // CodeGenerator |
| 294 | 294 |
| 295 class CodeGenerator: public AstVisitor { | 295 class CodeGenerator: public AstVisitor { |
| 296 public: | 296 public: |
| 297 // Compilation mode. Either the compiler is used as the primary | |
| 298 // compiler and needs to setup everything or the compiler is used as | |
| 299 // the secondary compiler for split compilation and has to handle | |
| 300 // bailouts. | |
| 301 enum Mode { | |
| 302 PRIMARY, | |
| 303 SECONDARY | |
| 304 }; | |
| 305 | |
| 306 // Takes a function literal, generates code for it. This function should only | 297 // Takes a function literal, generates code for it. This function should only |
| 307 // be called by compiler.cc. | 298 // be called by compiler.cc. |
| 308 static Handle<Code> MakeCode(CompilationInfo* info); | 299 static Handle<Code> MakeCode(CompilationInfo* info); |
| 309 | 300 |
| 310 // Printing of AST, etc. as requested by flags. | 301 // Printing of AST, etc. as requested by flags. |
| 311 static void MakeCodePrologue(CompilationInfo* info); | 302 static void MakeCodePrologue(CompilationInfo* info); |
| 312 | 303 |
| 313 // Allocate and install the code. | 304 // Allocate and install the code. |
| 314 static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm, | 305 static Handle<Code> MakeCodeEpilogue(MacroAssembler* masm, |
| 315 Code::Flags flags, | 306 Code::Flags flags, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 // reach the end of the statement (ie, it does not exit via break, | 368 // reach the end of the statement (ie, it does not exit via break, |
| 378 // continue, return, or throw). This function is used temporarily while | 369 // continue, return, or throw). This function is used temporarily while |
| 379 // the code generator is being transformed. | 370 // the code generator is being transformed. |
| 380 void VisitAndSpill(Statement* statement); | 371 void VisitAndSpill(Statement* statement); |
| 381 | 372 |
| 382 // Visit a list of statements and then spill the virtual frame if control | 373 // Visit a list of statements and then spill the virtual frame if control |
| 383 // flow can reach the end of the list. | 374 // flow can reach the end of the list. |
| 384 void VisitStatementsAndSpill(ZoneList<Statement*>* statements); | 375 void VisitStatementsAndSpill(ZoneList<Statement*>* statements); |
| 385 | 376 |
| 386 // Main code generation function | 377 // Main code generation function |
| 387 void Generate(CompilationInfo* info, Mode mode); | 378 void Generate(CompilationInfo* info); |
| 388 | 379 |
| 389 // Generate the return sequence code. Should be called no more than | 380 // Generate the return sequence code. Should be called no more than |
| 390 // once per compiled function, immediately after binding the return | 381 // once per compiled function, immediately after binding the return |
| 391 // target (which can not be done more than once). | 382 // target (which can not be done more than once). |
| 392 void GenerateReturnSequence(Result* return_value); | 383 void GenerateReturnSequence(Result* return_value); |
| 393 | 384 |
| 394 // Returns the arguments allocation mode. | 385 // Returns the arguments allocation mode. |
| 395 ArgumentsAllocationMode ArgumentsMode(); | 386 ArgumentsAllocationMode ArgumentsMode(); |
| 396 | 387 |
| 397 // Store the arguments object and allocate it if necessary. | 388 // Store the arguments object and allocate it if necessary. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 422 void Load(Expression* expr); | 413 void Load(Expression* expr); |
| 423 void LoadGlobal(); | 414 void LoadGlobal(); |
| 424 void LoadGlobalReceiver(); | 415 void LoadGlobalReceiver(); |
| 425 | 416 |
| 426 // Generate code to push the value of an expression on top of the frame | 417 // Generate code to push the value of an expression on top of the frame |
| 427 // and then spill the frame fully to memory. This function is used | 418 // and then spill the frame fully to memory. This function is used |
| 428 // temporarily while the code generator is being transformed. | 419 // temporarily while the code generator is being transformed. |
| 429 void LoadAndSpill(Expression* expression); | 420 void LoadAndSpill(Expression* expression); |
| 430 | 421 |
| 431 // Read a value from a slot and leave it on top of the expression stack. | 422 // Read a value from a slot and leave it on top of the expression stack. |
| 432 void LoadFromSlot(Slot* slot, TypeofState typeof_state); | 423 Result LoadFromSlot(Slot* slot, TypeofState typeof_state); |
| 433 void LoadFromSlotCheckForArguments(Slot* slot, TypeofState typeof_state); | 424 Result LoadFromSlotCheckForArguments(Slot* slot, TypeofState typeof_state); |
| 434 Result LoadFromGlobalSlotCheckExtensions(Slot* slot, | 425 Result LoadFromGlobalSlotCheckExtensions(Slot* slot, |
| 435 TypeofState typeof_state, | 426 TypeofState typeof_state, |
| 436 JumpTarget* slow); | 427 JumpTarget* slow); |
| 437 | 428 |
| 438 // Store the value on top of the expression stack into a slot, leaving the | 429 // Store the value on top of the expression stack into a slot, leaving the |
| 439 // value in place. | 430 // value in place. |
| 440 void StoreToSlot(Slot* slot, InitState init_state); | 431 void StoreToSlot(Slot* slot, InitState init_state); |
| 441 | 432 |
| 442 // Load a property of an object, returning it in a Result. | 433 // Support for compiling assignment expressions. |
| 443 // The object and the property name are passed on the stack, and | 434 void EmitSlotAssignment(Assignment* node); |
| 444 // not changed. | 435 void EmitNamedPropertyAssignment(Assignment* node); |
| 445 Result EmitKeyedLoad(bool is_global); | 436 void EmitKeyedPropertyAssignment(Assignment* node); |
| 437 |
| 438 // Receiver is passed on the frame and consumed. |
| 439 Result EmitNamedLoad(Handle<String> name, bool is_contextual); |
| 440 |
| 441 // If the store is contextual, value is passed on the frame and consumed. |
| 442 // Otherwise, receiver and value are passed on the frame and consumed. |
| 443 Result EmitNamedStore(Handle<String> name, bool is_contextual); |
| 444 |
| 445 // Receiver and key are passed on the frame and consumed. |
| 446 Result EmitKeyedLoad(); |
| 447 |
| 448 // Receiver, key, and value are passed on the frame and consumed. |
| 449 Result EmitKeyedStore(StaticType* key_type); |
| 446 | 450 |
| 447 // Special code for typeof expressions: Unfortunately, we must | 451 // Special code for typeof expressions: Unfortunately, we must |
| 448 // be careful when loading the expression in 'typeof' | 452 // be careful when loading the expression in 'typeof' |
| 449 // expressions. We are not allowed to throw reference errors for | 453 // expressions. We are not allowed to throw reference errors for |
| 450 // non-existing properties of the global object, so we must make it | 454 // non-existing properties of the global object, so we must make it |
| 451 // look like an explicit property access, instead of an access | 455 // look like an explicit property access, instead of an access |
| 452 // through the context chain. | 456 // through the context chain. |
| 453 void LoadTypeofExpression(Expression* x); | 457 void LoadTypeofExpression(Expression* x); |
| 454 | 458 |
| 455 // Translate the value on top of the frame into control flow to the | 459 // Translate the value on top of the frame into control flow to the |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 | 530 |
| 527 void ProcessDeclarations(ZoneList<Declaration*>* declarations); | 531 void ProcessDeclarations(ZoneList<Declaration*>* declarations); |
| 528 | 532 |
| 529 static Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop); | 533 static Handle<Code> ComputeCallInitialize(int argc, InLoopFlag in_loop); |
| 530 | 534 |
| 531 // Declare global variables and functions in the given array of | 535 // Declare global variables and functions in the given array of |
| 532 // name/value pairs. | 536 // name/value pairs. |
| 533 void DeclareGlobals(Handle<FixedArray> pairs); | 537 void DeclareGlobals(Handle<FixedArray> pairs); |
| 534 | 538 |
| 535 // Instantiate the function boilerplate. | 539 // Instantiate the function boilerplate. |
| 536 void InstantiateBoilerplate(Handle<JSFunction> boilerplate); | 540 Result InstantiateBoilerplate(Handle<JSFunction> boilerplate); |
| 537 | 541 |
| 538 // Support for type checks. | 542 // Support for type checks. |
| 539 void GenerateIsSmi(ZoneList<Expression*>* args); | 543 void GenerateIsSmi(ZoneList<Expression*>* args); |
| 540 void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); | 544 void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); |
| 541 void GenerateIsArray(ZoneList<Expression*>* args); | 545 void GenerateIsArray(ZoneList<Expression*>* args); |
| 546 void GenerateIsRegExp(ZoneList<Expression*>* args); |
| 542 void GenerateIsObject(ZoneList<Expression*>* args); | 547 void GenerateIsObject(ZoneList<Expression*>* args); |
| 543 void GenerateIsFunction(ZoneList<Expression*>* args); | 548 void GenerateIsFunction(ZoneList<Expression*>* args); |
| 544 void GenerateIsUndetectableObject(ZoneList<Expression*>* args); | 549 void GenerateIsUndetectableObject(ZoneList<Expression*>* args); |
| 545 | 550 |
| 546 // Support for construct call checks. | 551 // Support for construct call checks. |
| 547 void GenerateIsConstructCall(ZoneList<Expression*>* args); | 552 void GenerateIsConstructCall(ZoneList<Expression*>* args); |
| 548 | 553 |
| 549 // Support for arguments.length and arguments[?]. | 554 // Support for arguments.length and arguments[?]. |
| 550 void GenerateArgumentsLength(ZoneList<Expression*>* args); | 555 void GenerateArgumentsLength(ZoneList<Expression*>* args); |
| 551 void GenerateArgumentsAccess(ZoneList<Expression*>* args); | 556 void GenerateArgumentsAccess(ZoneList<Expression*>* args); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 573 | 578 |
| 574 // Fast support for SubString. | 579 // Fast support for SubString. |
| 575 void GenerateSubString(ZoneList<Expression*>* args); | 580 void GenerateSubString(ZoneList<Expression*>* args); |
| 576 | 581 |
| 577 // Fast support for StringCompare. | 582 // Fast support for StringCompare. |
| 578 void GenerateStringCompare(ZoneList<Expression*>* args); | 583 void GenerateStringCompare(ZoneList<Expression*>* args); |
| 579 | 584 |
| 580 // Support for direct calls from JavaScript to native RegExp code. | 585 // Support for direct calls from JavaScript to native RegExp code. |
| 581 void GenerateRegExpExec(ZoneList<Expression*>* args); | 586 void GenerateRegExpExec(ZoneList<Expression*>* args); |
| 582 | 587 |
| 588 // Fast support for number to string. |
| 589 void GenerateNumberToString(ZoneList<Expression*>* args); |
| 590 |
| 591 // Fast call to transcendental functions. |
| 592 void GenerateMathSin(ZoneList<Expression*>* args); |
| 593 void GenerateMathCos(ZoneList<Expression*>* args); |
| 594 |
| 583 // Simple condition analysis. | 595 // Simple condition analysis. |
| 584 enum ConditionAnalysis { | 596 enum ConditionAnalysis { |
| 585 ALWAYS_TRUE, | 597 ALWAYS_TRUE, |
| 586 ALWAYS_FALSE, | 598 ALWAYS_FALSE, |
| 587 DONT_KNOW | 599 DONT_KNOW |
| 588 }; | 600 }; |
| 589 ConditionAnalysis AnalyzeCondition(Expression* cond); | 601 ConditionAnalysis AnalyzeCondition(Expression* cond); |
| 590 | 602 |
| 591 // Methods used to indicate which source code is generated for. Source | 603 // Methods used to indicate which source code is generated for. Source |
| 592 // positions are collected by the assembler and emitted with the relocation | 604 // positions are collected by the assembler and emitted with the relocation |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 friend class FastCodeGenerator; | 652 friend class FastCodeGenerator; |
| 641 friend class FullCodeGenerator; | 653 friend class FullCodeGenerator; |
| 642 friend class FullCodeGenSyntaxChecker; | 654 friend class FullCodeGenSyntaxChecker; |
| 643 | 655 |
| 644 friend class CodeGeneratorPatcher; // Used in test-log-stack-tracer.cc | 656 friend class CodeGeneratorPatcher; // Used in test-log-stack-tracer.cc |
| 645 | 657 |
| 646 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 658 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); |
| 647 }; | 659 }; |
| 648 | 660 |
| 649 | 661 |
| 662 // Compute a transcendental math function natively, or call the |
| 663 // TranscendentalCache runtime function. |
| 664 class TranscendentalCacheStub: public CodeStub { |
| 665 public: |
| 666 explicit TranscendentalCacheStub(TranscendentalCache::Type type) |
| 667 : type_(type) {} |
| 668 void Generate(MacroAssembler* masm); |
| 669 private: |
| 670 TranscendentalCache::Type type_; |
| 671 Major MajorKey() { return TranscendentalCache; } |
| 672 int MinorKey() { return type_; } |
| 673 Runtime::FunctionId RuntimeFunction(); |
| 674 void GenerateOperation(MacroAssembler* masm); |
| 675 }; |
| 676 |
| 677 |
| 650 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. | 678 // Flag that indicates how to generate code for the stub GenericBinaryOpStub. |
| 651 enum GenericBinaryFlags { | 679 enum GenericBinaryFlags { |
| 652 NO_GENERIC_BINARY_FLAGS = 0, | 680 NO_GENERIC_BINARY_FLAGS = 0, |
| 653 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. | 681 NO_SMI_CODE_IN_STUB = 1 << 0 // Omit smi code in stub. |
| 654 }; | 682 }; |
| 655 | 683 |
| 656 | 684 |
| 657 class GenericBinaryOpStub: public CodeStub { | 685 class GenericBinaryOpStub: public CodeStub { |
| 658 public: | 686 public: |
| 659 GenericBinaryOpStub(Token::Value op, | 687 GenericBinaryOpStub(Token::Value op, |
| 660 OverwriteMode mode, | 688 OverwriteMode mode, |
| 661 GenericBinaryFlags flags) | 689 GenericBinaryFlags flags, |
| 690 NumberInfo::Type operands_type = NumberInfo::kUnknown) |
| 662 : op_(op), | 691 : op_(op), |
| 663 mode_(mode), | 692 mode_(mode), |
| 664 flags_(flags), | 693 flags_(flags), |
| 665 args_in_registers_(false), | 694 args_in_registers_(false), |
| 666 args_reversed_(false), | 695 args_reversed_(false), |
| 667 name_(NULL) { | 696 name_(NULL), |
| 697 operands_type_(operands_type) { |
| 668 use_sse3_ = CpuFeatures::IsSupported(SSE3); | 698 use_sse3_ = CpuFeatures::IsSupported(SSE3); |
| 669 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); | 699 ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
| 670 } | 700 } |
| 671 | 701 |
| 672 // Generate code to call the stub with the supplied arguments. This will add | 702 // Generate code to call the stub with the supplied arguments. This will add |
| 673 // code at the call site to prepare arguments either in registers or on the | 703 // code at the call site to prepare arguments either in registers or on the |
| 674 // stack together with the actual call. | 704 // stack together with the actual call. |
| 675 void GenerateCall(MacroAssembler* masm, Register left, Register right); | 705 void GenerateCall(MacroAssembler* masm, Register left, Register right); |
| 676 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); | 706 void GenerateCall(MacroAssembler* masm, Register left, Smi* right); |
| 677 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); | 707 void GenerateCall(MacroAssembler* masm, Smi* left, Register right); |
| 678 | 708 |
| 679 Result GenerateCall(MacroAssembler* masm, | 709 Result GenerateCall(MacroAssembler* masm, |
| 680 VirtualFrame* frame, | 710 VirtualFrame* frame, |
| 681 Result* left, | 711 Result* left, |
| 682 Result* right); | 712 Result* right); |
| 683 | 713 |
| 684 private: | 714 private: |
| 685 Token::Value op_; | 715 Token::Value op_; |
| 686 OverwriteMode mode_; | 716 OverwriteMode mode_; |
| 687 GenericBinaryFlags flags_; | 717 GenericBinaryFlags flags_; |
| 688 bool args_in_registers_; // Arguments passed in registers not on the stack. | 718 bool args_in_registers_; // Arguments passed in registers not on the stack. |
| 689 bool args_reversed_; // Left and right argument are swapped. | 719 bool args_reversed_; // Left and right argument are swapped. |
| 690 bool use_sse3_; | 720 bool use_sse3_; |
| 691 char* name_; | 721 char* name_; |
| 722 NumberInfo::Type operands_type_; // Number type information of operands. |
| 692 | 723 |
| 693 const char* GetName(); | 724 const char* GetName(); |
| 694 | 725 |
| 695 #ifdef DEBUG | 726 #ifdef DEBUG |
| 696 void Print() { | 727 void Print() { |
| 697 PrintF("GenericBinaryOpStub (op %s), " | 728 PrintF("GenericBinaryOpStub %d (op %s), " |
| 698 "(mode %d, flags %d, registers %d, reversed %d)\n", | 729 "(mode %d, flags %d, registers %d, reversed %d, number_info %s)\n", |
| 730 MinorKey(), |
| 699 Token::String(op_), | 731 Token::String(op_), |
| 700 static_cast<int>(mode_), | 732 static_cast<int>(mode_), |
| 701 static_cast<int>(flags_), | 733 static_cast<int>(flags_), |
| 702 static_cast<int>(args_in_registers_), | 734 static_cast<int>(args_in_registers_), |
| 703 static_cast<int>(args_reversed_)); | 735 static_cast<int>(args_reversed_), |
| 736 NumberInfo::ToString(operands_type_)); |
| 704 } | 737 } |
| 705 #endif | 738 #endif |
| 706 | 739 |
| 707 // Minor key encoding in 16 bits FRASOOOOOOOOOOMM. | 740 // Minor key encoding in 16 bits NNNFRASOOOOOOOMM. |
| 708 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; | 741 class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
| 709 class OpBits: public BitField<Token::Value, 2, 10> {}; | 742 class OpBits: public BitField<Token::Value, 2, 7> {}; |
| 710 class SSE3Bits: public BitField<bool, 12, 1> {}; | 743 class SSE3Bits: public BitField<bool, 9, 1> {}; |
| 711 class ArgsInRegistersBits: public BitField<bool, 13, 1> {}; | 744 class ArgsInRegistersBits: public BitField<bool, 10, 1> {}; |
| 712 class ArgsReversedBits: public BitField<bool, 14, 1> {}; | 745 class ArgsReversedBits: public BitField<bool, 11, 1> {}; |
| 713 class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {}; | 746 class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {}; |
| 747 class NumberInfoBits: public BitField<NumberInfo::Type, 13, 3> {}; |
| 714 | 748 |
| 715 Major MajorKey() { return GenericBinaryOp; } | 749 Major MajorKey() { return GenericBinaryOp; } |
| 716 int MinorKey() { | 750 int MinorKey() { |
| 717 // Encode the parameters in a unique 16 bit value. | 751 // Encode the parameters in a unique 16 bit value. |
| 718 return OpBits::encode(op_) | 752 return OpBits::encode(op_) |
| 719 | ModeBits::encode(mode_) | 753 | ModeBits::encode(mode_) |
| 720 | FlagBits::encode(flags_) | 754 | FlagBits::encode(flags_) |
| 721 | SSE3Bits::encode(use_sse3_) | 755 | SSE3Bits::encode(use_sse3_) |
| 722 | ArgsInRegistersBits::encode(args_in_registers_) | 756 | ArgsInRegistersBits::encode(args_in_registers_) |
| 723 | ArgsReversedBits::encode(args_reversed_); | 757 | ArgsReversedBits::encode(args_reversed_) |
| 758 | NumberInfoBits::encode(operands_type_); |
| 724 } | 759 } |
| 725 | 760 |
| 726 void Generate(MacroAssembler* masm); | 761 void Generate(MacroAssembler* masm); |
| 727 void GenerateSmiCode(MacroAssembler* masm, Label* slow); | 762 void GenerateSmiCode(MacroAssembler* masm, Label* slow); |
| 728 void GenerateLoadArguments(MacroAssembler* masm); | 763 void GenerateLoadArguments(MacroAssembler* masm); |
| 729 void GenerateReturn(MacroAssembler* masm); | 764 void GenerateReturn(MacroAssembler* masm); |
| 730 void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure); | 765 void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure); |
| 731 | 766 |
| 732 bool ArgsInRegistersSupported() { | 767 bool ArgsInRegistersSupported() { |
| 733 return op_ == Token::ADD || op_ == Token::SUB | 768 return op_ == Token::ADD || op_ == Token::SUB |
| (...skipping 26 matching lines...) Expand all Loading... |
| 760 | 795 |
| 761 // Generate code for copying characters using the rep movs instruction. | 796 // Generate code for copying characters using the rep movs instruction. |
| 762 // Copies ecx characters from esi to edi. Copying of overlapping regions is | 797 // Copies ecx characters from esi to edi. Copying of overlapping regions is |
| 763 // not supported. | 798 // not supported. |
| 764 void GenerateCopyCharactersREP(MacroAssembler* masm, | 799 void GenerateCopyCharactersREP(MacroAssembler* masm, |
| 765 Register dest, // Must be edi. | 800 Register dest, // Must be edi. |
| 766 Register src, // Must be esi. | 801 Register src, // Must be esi. |
| 767 Register count, // Must be ecx. | 802 Register count, // Must be ecx. |
| 768 Register scratch, // Neither of the above. | 803 Register scratch, // Neither of the above. |
| 769 bool ascii); | 804 bool ascii); |
| 805 |
| 806 // Probe the symbol table for a two character string. If the string is |
| 807 // not found by probing a jump to the label not_found is performed. This jump |
| 808 // does not guarantee that the string is not in the symbol table. If the |
| 809 // string is found the code falls through with the string in register eax. |
| 810 void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, |
| 811 Register c1, |
| 812 Register c2, |
| 813 Register scratch1, |
| 814 Register scratch2, |
| 815 Register scratch3, |
| 816 Label* not_found); |
| 817 |
| 818 // Generate string hash. |
| 819 void GenerateHashInit(MacroAssembler* masm, |
| 820 Register hash, |
| 821 Register character, |
| 822 Register scratch); |
| 823 void GenerateHashAddCharacter(MacroAssembler* masm, |
| 824 Register hash, |
| 825 Register character, |
| 826 Register scratch); |
| 827 void GenerateHashGetHash(MacroAssembler* masm, |
| 828 Register hash, |
| 829 Register scratch); |
| 770 }; | 830 }; |
| 771 | 831 |
| 772 | 832 |
| 773 // Flag that indicates how to generate code for the stub StringAddStub. | 833 // Flag that indicates how to generate code for the stub StringAddStub. |
| 774 enum StringAddFlags { | 834 enum StringAddFlags { |
| 775 NO_STRING_ADD_FLAGS = 0, | 835 NO_STRING_ADD_FLAGS = 0, |
| 776 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. | 836 NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. |
| 777 }; | 837 }; |
| 778 | 838 |
| 779 | 839 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 Register scratch3); | 881 Register scratch3); |
| 822 | 882 |
| 823 private: | 883 private: |
| 824 Major MajorKey() { return StringCompare; } | 884 Major MajorKey() { return StringCompare; } |
| 825 int MinorKey() { return 0; } | 885 int MinorKey() { return 0; } |
| 826 | 886 |
| 827 void Generate(MacroAssembler* masm); | 887 void Generate(MacroAssembler* masm); |
| 828 }; | 888 }; |
| 829 | 889 |
| 830 | 890 |
| 891 class NumberToStringStub: public CodeStub { |
| 892 public: |
| 893 NumberToStringStub() { } |
| 894 |
| 895 // Generate code to do a lookup in the number string cache. If the number in |
| 896 // the register object is found in the cache the generated code falls through |
| 897 // with the result in the result register. The object and the result register |
| 898 // can be the same. If the number is not found in the cache the code jumps to |
| 899 // the label not_found with only the content of register object unchanged. |
| 900 static void GenerateLookupNumberStringCache(MacroAssembler* masm, |
| 901 Register object, |
| 902 Register result, |
| 903 Register scratch1, |
| 904 Register scratch2, |
| 905 bool object_is_smi, |
| 906 Label* not_found); |
| 907 |
| 908 private: |
| 909 Major MajorKey() { return NumberToString; } |
| 910 int MinorKey() { return 0; } |
| 911 |
| 912 void Generate(MacroAssembler* masm); |
| 913 |
| 914 const char* GetName() { return "NumberToStringStub"; } |
| 915 |
| 916 #ifdef DEBUG |
| 917 void Print() { |
| 918 PrintF("NumberToStringStub\n"); |
| 919 } |
| 920 #endif |
| 921 }; |
| 922 |
| 923 |
| 831 } } // namespace v8::internal | 924 } } // namespace v8::internal |
| 832 | 925 |
| 833 #endif // V8_IA32_CODEGEN_IA32_H_ | 926 #endif // V8_IA32_CODEGEN_IA32_H_ |
| OLD | NEW |