diff options
Diffstat (limited to 'deps/v8/src/arm/codegen-arm.h')
-rw-r--r-- | deps/v8/src/arm/codegen-arm.h | 522 |
1 files changed, 10 insertions, 512 deletions
diff --git a/deps/v8/src/arm/codegen-arm.h b/deps/v8/src/arm/codegen-arm.h index 029d59900d..162d97fd98 100644 --- a/deps/v8/src/arm/codegen-arm.h +++ b/deps/v8/src/arm/codegen-arm.h @@ -28,8 +28,9 @@ #ifndef V8_ARM_CODEGEN_ARM_H_ #define V8_ARM_CODEGEN_ARM_H_ -#include "ic-inl.h" #include "ast.h" +#include "code-stubs-arm.h" +#include "ic-inl.h" namespace v8 { namespace internal { @@ -270,15 +271,13 @@ class CodeGenerator: public AstVisitor { void AddDeferred(DeferredCode* code) { deferred_.Add(code); } - static const int kUnknownIntValue = -1; - // If the name is an inline runtime function call return the number of // expected arguments. Otherwise return -1. static int InlineRuntimeCallArgumentsCount(Handle<String> name); // Constants related to patching of inlined load/store. static int GetInlinedKeyedLoadInstructionsAfterPatch() { - return FLAG_debug_code ? 27 : 13; + return FLAG_debug_code ? 32 : 13; } static const int kInlinedKeyedStoreInstructionsAfterPatch = 5; static int GetInlinedNamedStoreInstructionsAfterPatch() { @@ -420,7 +419,8 @@ class CodeGenerator: public AstVisitor { void GenericBinaryOperation(Token::Value op, OverwriteMode overwrite_mode, GenerateInlineSmi inline_smi, - int known_rhs = kUnknownIntValue); + int known_rhs = + GenericBinaryOpStub::kUnknownIntValue); void Comparison(Condition cc, Expression* left, Expression* right, @@ -455,9 +455,6 @@ class CodeGenerator: public AstVisitor { static InlineRuntimeLUT* FindInlineRuntimeLUT(Handle<String> name); bool CheckForInlineRuntimeCall(CallRuntime* node); - static bool PatchInlineRuntimeEntry(Handle<String> name, - const InlineRuntimeLUT& new_entry, - InlineRuntimeLUT* old_entry); static Handle<Code> ComputeLazyCompile(int argc); void ProcessDeclarations(ZoneList<Declaration*>* declarations); @@ -528,6 +525,8 @@ class CodeGenerator: public AstVisitor { void GenerateRegExpConstructResult(ZoneList<Expression*>* args); + void GenerateRegExpCloneResult(ZoneList<Expression*>* args); + // Support for fast native caches. void GenerateGetFromCache(ZoneList<Expression*>* args); @@ -548,6 +547,9 @@ class CodeGenerator: public AstVisitor { void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args); + void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args); + void GenerateGetCachedArrayIndex(ZoneList<Expression*>* args); + // Simple condition analysis. enum ConditionAnalysis { ALWAYS_TRUE, @@ -610,510 +612,6 @@ class CodeGenerator: public AstVisitor { }; -// Compute a transcendental math function natively, or call the -// TranscendentalCache runtime function. -class TranscendentalCacheStub: public CodeStub { - public: - explicit TranscendentalCacheStub(TranscendentalCache::Type type) - : type_(type) {} - void Generate(MacroAssembler* masm); - private: - TranscendentalCache::Type type_; - Major MajorKey() { return TranscendentalCache; } - int MinorKey() { return type_; } - Runtime::FunctionId RuntimeFunction(); -}; - - -class ToBooleanStub: public CodeStub { - public: - explicit ToBooleanStub(Register tos) : tos_(tos) { } - - void Generate(MacroAssembler* masm); - - private: - Register tos_; - Major MajorKey() { return ToBoolean; } - int MinorKey() { return tos_.code(); } -}; - - -class GenericBinaryOpStub : public CodeStub { - public: - GenericBinaryOpStub(Token::Value op, - OverwriteMode mode, - Register lhs, - Register rhs, - int constant_rhs = CodeGenerator::kUnknownIntValue) - : op_(op), - mode_(mode), - lhs_(lhs), - rhs_(rhs), - constant_rhs_(constant_rhs), - specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)), - runtime_operands_type_(BinaryOpIC::DEFAULT), - name_(NULL) { } - - GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) - : op_(OpBits::decode(key)), - mode_(ModeBits::decode(key)), - lhs_(LhsRegister(RegisterBits::decode(key))), - rhs_(RhsRegister(RegisterBits::decode(key))), - constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))), - specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)), - runtime_operands_type_(type_info), - name_(NULL) { } - - private: - Token::Value op_; - OverwriteMode mode_; - Register lhs_; - Register rhs_; - int constant_rhs_; - bool specialized_on_rhs_; - BinaryOpIC::TypeInfo runtime_operands_type_; - char* name_; - - static const int kMaxKnownRhs = 0x40000000; - static const int kKnownRhsKeyBits = 6; - - // Minor key encoding in 17 bits. - class ModeBits: public BitField<OverwriteMode, 0, 2> {}; - class OpBits: public BitField<Token::Value, 2, 6> {}; - class TypeInfoBits: public BitField<int, 8, 2> {}; - class RegisterBits: public BitField<bool, 10, 1> {}; - class KnownIntBits: public BitField<int, 11, kKnownRhsKeyBits> {}; - - Major MajorKey() { return GenericBinaryOp; } - int MinorKey() { - ASSERT((lhs_.is(r0) && rhs_.is(r1)) || - (lhs_.is(r1) && rhs_.is(r0))); - // Encode the parameters in a unique 18 bit value. - return OpBits::encode(op_) - | ModeBits::encode(mode_) - | KnownIntBits::encode(MinorKeyForKnownInt()) - | TypeInfoBits::encode(runtime_operands_type_) - | RegisterBits::encode(lhs_.is(r0)); - } - - void Generate(MacroAssembler* masm); - void HandleNonSmiBitwiseOp(MacroAssembler* masm, - Register lhs, - Register rhs); - void HandleBinaryOpSlowCases(MacroAssembler* masm, - Label* not_smi, - Register lhs, - Register rhs, - const Builtins::JavaScript& builtin); - void GenerateTypeTransition(MacroAssembler* masm); - - static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) { - if (constant_rhs == CodeGenerator::kUnknownIntValue) return false; - if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3; - if (op == Token::MOD) { - if (constant_rhs <= 1) return false; - if (constant_rhs <= 10) return true; - if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true; - return false; - } - return false; - } - - int MinorKeyForKnownInt() { - if (!specialized_on_rhs_) return 0; - if (constant_rhs_ <= 10) return constant_rhs_ + 1; - ASSERT(IsPowerOf2(constant_rhs_)); - int key = 12; - int d = constant_rhs_; - while ((d & 1) == 0) { - key++; - d >>= 1; - } - ASSERT(key >= 0 && key < (1 << kKnownRhsKeyBits)); - return key; - } - - int KnownBitsForMinorKey(int key) { - if (!key) return 0; - if (key <= 11) return key - 1; - int d = 1; - while (key != 12) { - key--; - d <<= 1; - } - return d; - } - - Register LhsRegister(bool lhs_is_r0) { - return lhs_is_r0 ? r0 : r1; - } - - Register RhsRegister(bool lhs_is_r0) { - return lhs_is_r0 ? r1 : r0; - } - - bool ShouldGenerateSmiCode() { - return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) && - runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && - runtime_operands_type_ != BinaryOpIC::STRINGS; - } - - bool ShouldGenerateFPCode() { - return runtime_operands_type_ != BinaryOpIC::STRINGS; - } - - virtual int GetCodeKind() { return Code::BINARY_OP_IC; } - - virtual InlineCacheState GetICState() { - return BinaryOpIC::ToState(runtime_operands_type_); - } - - const char* GetName(); - -#ifdef DEBUG - void Print() { - if (!specialized_on_rhs_) { - PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); - } else { - PrintF("GenericBinaryOpStub (%s by %d)\n", - Token::String(op_), - constant_rhs_); - } - } -#endif -}; - - -class StringHelper : public AllStatic { - public: - // Generate code for copying characters using a simple loop. This should only - // be used in places where the number of characters is small and the - // additional setup and checking in GenerateCopyCharactersLong adds too much - // overhead. Copying of overlapping regions is not supported. - // Dest register ends at the position after the last character written. - static void GenerateCopyCharacters(MacroAssembler* masm, - Register dest, - Register src, - Register count, - Register scratch, - bool ascii); - - // Generate code for copying a large number of characters. This function - // is allowed to spend extra time setting up conditions to make copying - // faster. Copying of overlapping regions is not supported. - // Dest register ends at the position after the last character written. - static void GenerateCopyCharactersLong(MacroAssembler* masm, - Register dest, - Register src, - Register count, - Register scratch1, - Register scratch2, - Register scratch3, - Register scratch4, - Register scratch5, - int flags); - - - // Probe the symbol table for a two character string. If the string is - // not found by probing a jump to the label not_found is performed. This jump - // does not guarantee that the string is not in the symbol table. If the - // string is found the code falls through with the string in register r0. - // Contents of both c1 and c2 registers are modified. At the exit c1 is - // guaranteed to contain halfword with low and high bytes equal to - // initial contents of c1 and c2 respectively. - static void GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, - Register c1, - Register c2, - Register scratch1, - Register scratch2, - Register scratch3, - Register scratch4, - Register scratch5, - Label* not_found); - - // Generate string hash. - static void GenerateHashInit(MacroAssembler* masm, - Register hash, - Register character); - - static void GenerateHashAddCharacter(MacroAssembler* masm, - Register hash, - Register character); - - static void GenerateHashGetHash(MacroAssembler* masm, - Register hash); - - private: - DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper); -}; - - -// Flag that indicates how to generate code for the stub StringAddStub. -enum StringAddFlags { - NO_STRING_ADD_FLAGS = 0, - NO_STRING_CHECK_IN_STUB = 1 << 0 // Omit string check in stub. -}; - - -class StringAddStub: public CodeStub { - public: - explicit StringAddStub(StringAddFlags flags) { - string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0); - } - - private: - Major MajorKey() { return StringAdd; } - int MinorKey() { return string_check_ ? 0 : 1; } - - void Generate(MacroAssembler* masm); - - // Should the stub check whether arguments are strings? - bool string_check_; -}; - - -class SubStringStub: public CodeStub { - public: - SubStringStub() {} - - private: - Major MajorKey() { return SubString; } - int MinorKey() { return 0; } - - void Generate(MacroAssembler* masm); -}; - - - -class StringCompareStub: public CodeStub { - public: - StringCompareStub() { } - - // Compare two flat ASCII strings and returns result in r0. - // Does not use the stack. - static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm, - Register left, - Register right, - Register scratch1, - Register scratch2, - Register scratch3, - Register scratch4); - - private: - Major MajorKey() { return StringCompare; } - int MinorKey() { return 0; } - - void Generate(MacroAssembler* masm); -}; - - -// This stub can do a fast mod operation without using fp. -// It is tail called from the GenericBinaryOpStub and it always -// returns an answer. It never causes GC so it doesn't need a real frame. -// -// The inputs are always positive Smis. This is never called -// where the denominator is a power of 2. We handle that separately. -// -// If we consider the denominator as an odd number multiplied by a power of 2, -// then: -// * The exponent (power of 2) is in the shift_distance register. -// * The odd number is in the odd_number register. It is always in the range -// of 3 to 25. -// * The bits from the numerator that are to be copied to the answer (there are -// shift_distance of them) are in the mask_bits register. -// * The other bits of the numerator have been shifted down and are in the lhs -// register. -class IntegerModStub : public CodeStub { - public: - IntegerModStub(Register result, - Register shift_distance, - Register odd_number, - Register mask_bits, - Register lhs, - Register scratch) - : result_(result), - shift_distance_(shift_distance), - odd_number_(odd_number), - mask_bits_(mask_bits), - lhs_(lhs), - scratch_(scratch) { - // We don't code these in the minor key, so they should always be the same. - // We don't really want to fix that since this stub is rather large and we - // don't want many copies of it. - ASSERT(shift_distance_.is(r9)); - ASSERT(odd_number_.is(r4)); - ASSERT(mask_bits_.is(r3)); - ASSERT(scratch_.is(r5)); - } - - private: - Register result_; - Register shift_distance_; - Register odd_number_; - Register mask_bits_; - Register lhs_; - Register scratch_; - - // Minor key encoding in 16 bits. - class ResultRegisterBits: public BitField<int, 0, 4> {}; - class LhsRegisterBits: public BitField<int, 4, 4> {}; - - Major MajorKey() { return IntegerMod; } - int MinorKey() { - // Encode the parameters in a unique 16 bit value. - return ResultRegisterBits::encode(result_.code()) - | LhsRegisterBits::encode(lhs_.code()); - } - - void Generate(MacroAssembler* masm); - - const char* GetName() { return "IntegerModStub"; } - - // Utility functions. - void DigitSum(MacroAssembler* masm, - Register lhs, - int mask, - int shift, - Label* entry); - void DigitSum(MacroAssembler* masm, - Register lhs, - Register scratch, - int mask, - int shift1, - int shift2, - Label* entry); - void ModGetInRangeBySubtraction(MacroAssembler* masm, - Register lhs, - int shift, - int rhs); - void ModReduce(MacroAssembler* masm, - Register lhs, - int max, - int denominator); - void ModAnswer(MacroAssembler* masm, - Register result, - Register shift_distance, - Register mask_bits, - Register sum_of_digits); - - -#ifdef DEBUG - void Print() { PrintF("IntegerModStub\n"); } -#endif -}; - - -// This stub can convert a signed int32 to a heap number (double). It does -// not work for int32s that are in Smi range! No GC occurs during this stub -// so you don't have to set up the frame. -class WriteInt32ToHeapNumberStub : public CodeStub { - public: - WriteInt32ToHeapNumberStub(Register the_int, - Register the_heap_number, - Register scratch) - : the_int_(the_int), - the_heap_number_(the_heap_number), - scratch_(scratch) { } - - private: - Register the_int_; - Register the_heap_number_; - Register scratch_; - - // Minor key encoding in 16 bits. - class IntRegisterBits: public BitField<int, 0, 4> {}; - class HeapNumberRegisterBits: public BitField<int, 4, 4> {}; - class ScratchRegisterBits: public BitField<int, 8, 4> {}; - - Major MajorKey() { return WriteInt32ToHeapNumber; } - int MinorKey() { - // Encode the parameters in a unique 16 bit value. - return IntRegisterBits::encode(the_int_.code()) - | HeapNumberRegisterBits::encode(the_heap_number_.code()) - | ScratchRegisterBits::encode(scratch_.code()); - } - - void Generate(MacroAssembler* masm); - - const char* GetName() { return "WriteInt32ToHeapNumberStub"; } - -#ifdef DEBUG - void Print() { PrintF("WriteInt32ToHeapNumberStub\n"); } -#endif -}; - - -class NumberToStringStub: public CodeStub { - public: - NumberToStringStub() { } - - // Generate code to do a lookup in the number string cache. If the number in - // the register object is found in the cache the generated code falls through - // with the result in the result register. The object and the result register - // can be the same. If the number is not found in the cache the code jumps to - // the label not_found with only the content of register object unchanged. - static void GenerateLookupNumberStringCache(MacroAssembler* masm, - Register object, - Register result, - Register scratch1, - Register scratch2, - Register scratch3, - bool object_is_smi, - Label* not_found); - - private: - Major MajorKey() { return NumberToString; } - int MinorKey() { return 0; } - - void Generate(MacroAssembler* masm); - - const char* GetName() { return "NumberToStringStub"; } - -#ifdef DEBUG - void Print() { - PrintF("NumberToStringStub\n"); - } -#endif -}; - - -class RecordWriteStub : public CodeStub { - public: - RecordWriteStub(Register object, Register offset, Register scratch) - : object_(object), offset_(offset), scratch_(scratch) { } - - void Generate(MacroAssembler* masm); - - private: - Register object_; - Register offset_; - Register scratch_; - -#ifdef DEBUG - void Print() { - PrintF("RecordWriteStub (object reg %d), (offset reg %d)," - " (scratch reg %d)\n", - object_.code(), offset_.code(), scratch_.code()); - } -#endif - - // Minor key encoding in 12 bits. 4 bits for each of the three - // registers (object, offset and scratch) OOOOAAAASSSS. - class ScratchBits: public BitField<uint32_t, 0, 4> {}; - class OffsetBits: public BitField<uint32_t, 4, 4> {}; - class ObjectBits: public BitField<uint32_t, 8, 4> {}; - - Major MajorKey() { return RecordWrite; } - - int MinorKey() { - // Encode the registers. - return ObjectBits::encode(object_.code()) | - OffsetBits::encode(offset_.code()) | - ScratchBits::encode(scratch_.code()); - } -}; - - } } // namespace v8::internal #endif // V8_ARM_CODEGEN_ARM_H_ |