| Index: src/mips/code-stubs-mips.h
|
| diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
|
| index 675730a5534f9ce96c41eee96aa4d1849f21f384..d1307b5a859d9c7b5fd0eeb97f26276395e00976 100644
|
| --- a/src/mips/code-stubs-mips.h
|
| +++ b/src/mips/code-stubs-mips.h
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2010 the V8 project authors. All rights reserved.
|
| +// Copyright 2011 the V8 project authors. All rights reserved.
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| // met:
|
| @@ -39,13 +39,22 @@ namespace internal {
|
| // TranscendentalCache runtime function.
|
| class TranscendentalCacheStub: public CodeStub {
|
| public:
|
| - explicit TranscendentalCacheStub(TranscendentalCache::Type type)
|
| - : type_(type) {}
|
| + enum ArgumentType {
|
| + TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
|
| + UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
|
| + };
|
| +
|
| + TranscendentalCacheStub(TranscendentalCache::Type type,
|
| + ArgumentType argument_type)
|
| + : type_(type), argument_type_(argument_type) { }
|
| void Generate(MacroAssembler* masm);
|
| private:
|
| TranscendentalCache::Type type_;
|
| + ArgumentType argument_type_;
|
| + void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
|
| +
|
| Major MajorKey() { return TranscendentalCache; }
|
| - int MinorKey() { return type_; }
|
| + int MinorKey() { return type_ | argument_type_; }
|
| Runtime::FunctionId RuntimeFunction();
|
| };
|
|
|
| @@ -63,161 +72,92 @@ class ToBooleanStub: public CodeStub {
|
| };
|
|
|
|
|
| -class GenericBinaryOpStub : public CodeStub {
|
| +class TypeRecordingUnaryOpStub: public CodeStub {
|
| public:
|
| - static const int kUnknownIntValue = -1;
|
| -
|
| - GenericBinaryOpStub(Token::Value op,
|
| - OverwriteMode mode,
|
| - Register lhs,
|
| - Register rhs,
|
| - int constant_rhs = kUnknownIntValue)
|
| + TypeRecordingUnaryOpStub(Token::Value op, UnaryOverwriteMode mode)
|
| : op_(op),
|
| mode_(mode),
|
| - lhs_(lhs),
|
| - rhs_(rhs),
|
| - constant_rhs_(constant_rhs),
|
| - specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)),
|
| - runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI),
|
| - name_(NULL) { }
|
| + operand_type_(TRUnaryOpIC::UNINITIALIZED),
|
| + name_(NULL) {
|
| + }
|
|
|
| - GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info)
|
| + TypeRecordingUnaryOpStub(
|
| + int key,
|
| + TRUnaryOpIC::TypeInfo operand_type)
|
| : 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) { }
|
| + operand_type_(operand_type),
|
| + 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;
|
| + UnaryOverwriteMode mode_;
|
|
|
| - // Minor key encoding in 16 bits.
|
| - class ModeBits: public BitField<OverwriteMode, 0, 2> {};
|
| - class OpBits: public BitField<Token::Value, 2, 6> {};
|
| - class TypeInfoBits: public BitField<int, 8, 3> {};
|
| - class RegisterBits: public BitField<bool, 11, 1> {};
|
| - class KnownIntBits: public BitField<int, 12, kKnownRhsKeyBits> {};
|
| + // Operand type information determined at runtime.
|
| + TRUnaryOpIC::TypeInfo operand_type_;
|
|
|
| - Major MajorKey() { return GenericBinaryOp; }
|
| - int MinorKey() {
|
| - ASSERT((lhs_.is(a0) && rhs_.is(a1)) ||
|
| - (lhs_.is(a1) && rhs_.is(a0)));
|
| - // Encode the parameters in a unique 16 bit value.
|
| - return OpBits::encode(op_)
|
| - | ModeBits::encode(mode_)
|
| - | KnownIntBits::encode(MinorKeyForKnownInt())
|
| - | TypeInfoBits::encode(runtime_operands_type_)
|
| - | RegisterBits::encode(lhs_.is(a0));
|
| - }
|
| + char* name_;
|
|
|
| - 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);
|
| + const char* GetName();
|
|
|
| - static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) {
|
| - if (constant_rhs == 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;
|
| +#ifdef DEBUG
|
| + void Print() {
|
| + PrintF("TypeRecordingUnaryOpStub %d (op %s), "
|
| + "(mode %d, runtime_type_info %s)\n",
|
| + MinorKey(),
|
| + Token::String(op_),
|
| + static_cast<int>(mode_),
|
| + TRUnaryOpIC::GetName(operand_type_));
|
| }
|
| +#endif
|
|
|
| - 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;
|
| - }
|
| + class ModeBits: public BitField<UnaryOverwriteMode, 0, 1> {};
|
| + class OpBits: public BitField<Token::Value, 1, 7> {};
|
| + class OperandTypeInfoBits: public BitField<TRUnaryOpIC::TypeInfo, 8, 3> {};
|
|
|
| - 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;
|
| + Major MajorKey() { return TypeRecordingUnaryOp; }
|
| + int MinorKey() {
|
| + return ModeBits::encode(mode_)
|
| + | OpBits::encode(op_)
|
| + | OperandTypeInfoBits::encode(operand_type_);
|
| }
|
|
|
| - Register LhsRegister(bool lhs_is_a0) {
|
| - return lhs_is_a0 ? a0 : a1;
|
| - }
|
| + // Note: A lot of the helper functions below will vanish when we use virtual
|
| + // function instead of switch more often.
|
| + void Generate(MacroAssembler* masm);
|
|
|
| - Register RhsRegister(bool lhs_is_a0) {
|
| - return lhs_is_a0 ? a1 : a0;
|
| - }
|
| + void GenerateTypeTransition(MacroAssembler* masm);
|
|
|
| - bool HasSmiSmiFastPath() {
|
| - return op_ != Token::DIV;
|
| - }
|
| + void GenerateSmiStub(MacroAssembler* masm);
|
| + void GenerateSmiStubSub(MacroAssembler* masm);
|
| + void GenerateSmiStubBitNot(MacroAssembler* masm);
|
| + void GenerateSmiCodeSub(MacroAssembler* masm, Label* non_smi, Label* slow);
|
| + void GenerateSmiCodeBitNot(MacroAssembler* masm, Label* slow);
|
|
|
| - bool ShouldGenerateSmiCode() {
|
| - return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) &&
|
| - runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS &&
|
| - runtime_operands_type_ != BinaryOpIC::STRINGS;
|
| - }
|
| + void GenerateHeapNumberStub(MacroAssembler* masm);
|
| + void GenerateHeapNumberStubSub(MacroAssembler* masm);
|
| + void GenerateHeapNumberStubBitNot(MacroAssembler* masm);
|
| + void GenerateHeapNumberCodeSub(MacroAssembler* masm, Label* slow);
|
| + void GenerateHeapNumberCodeBitNot(MacroAssembler* masm, Label* slow);
|
|
|
| - bool ShouldGenerateFPCode() {
|
| - return runtime_operands_type_ != BinaryOpIC::STRINGS;
|
| - }
|
| + void GenerateGenericStub(MacroAssembler* masm);
|
| + void GenerateGenericStubSub(MacroAssembler* masm);
|
| + void GenerateGenericStubBitNot(MacroAssembler* masm);
|
| + void GenerateGenericCodeFallback(MacroAssembler* masm);
|
|
|
| - virtual int GetCodeKind() { return Code::BINARY_OP_IC; }
|
| + virtual int GetCodeKind() { return Code::TYPE_RECORDING_UNARY_OP_IC; }
|
|
|
| virtual InlineCacheState GetICState() {
|
| - return BinaryOpIC::ToState(runtime_operands_type_);
|
| + return TRUnaryOpIC::ToState(operand_type_);
|
| }
|
|
|
| - const char* GetName();
|
| -
|
| virtual void FinishCode(Code* code) {
|
| - code->set_binary_op_type(runtime_operands_type_);
|
| - }
|
| -
|
| -#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_);
|
| - }
|
| + code->set_type_recording_unary_op_type(operand_type_);
|
| }
|
| -#endif
|
| };
|
|
|
| +
|
| class TypeRecordingBinaryOpStub: public CodeStub {
|
| public:
|
| TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
|
| @@ -226,7 +166,8 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
| operands_type_(TRBinaryOpIC::UNINITIALIZED),
|
| result_type_(TRBinaryOpIC::UNINITIALIZED),
|
| name_(NULL) {
|
| - UNIMPLEMENTED_MIPS();
|
| + use_fpu_ = CpuFeatures::IsSupported(FPU);
|
| + ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
|
| }
|
|
|
| TypeRecordingBinaryOpStub(
|
| @@ -293,6 +234,7 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
| Label* not_numbers,
|
| Label* gc_required);
|
| void GenerateSmiCode(MacroAssembler* masm,
|
| + Label* use_runtime,
|
| Label* gc_required,
|
| SmiCodeGenerateHeapNumberResults heapnumber_results);
|
| void GenerateLoadArguments(MacroAssembler* masm);
|
| @@ -301,7 +243,9 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
| void GenerateSmiStub(MacroAssembler* masm);
|
| void GenerateInt32Stub(MacroAssembler* masm);
|
| void GenerateHeapNumberStub(MacroAssembler* masm);
|
| + void GenerateOddballStub(MacroAssembler* masm);
|
| void GenerateStringStub(MacroAssembler* masm);
|
| + void GenerateBothStringStub(MacroAssembler* masm);
|
| void GenerateGenericStub(MacroAssembler* masm);
|
| void GenerateAddStrings(MacroAssembler* masm);
|
| void GenerateCallRuntime(MacroAssembler* masm);
|
| @@ -334,24 +278,36 @@ class TypeRecordingBinaryOpStub: public CodeStub {
|
| // 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.
|
| + // Omit left string check in stub (left is definitely a string).
|
| + NO_STRING_CHECK_LEFT_IN_STUB = 1 << 0,
|
| + // Omit right string check in stub (right is definitely a string).
|
| + NO_STRING_CHECK_RIGHT_IN_STUB = 1 << 1,
|
| + // Omit both string checks in stub.
|
| + NO_STRING_CHECK_IN_STUB =
|
| + NO_STRING_CHECK_LEFT_IN_STUB | NO_STRING_CHECK_RIGHT_IN_STUB
|
| };
|
|
|
|
|
| class StringAddStub: public CodeStub {
|
| public:
|
| - explicit StringAddStub(StringAddFlags flags) {
|
| - string_check_ = ((flags & NO_STRING_CHECK_IN_STUB) == 0);
|
| - }
|
| + explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
|
|
|
| private:
|
| Major MajorKey() { return StringAdd; }
|
| - int MinorKey() { return string_check_ ? 0 : 1; }
|
| + int MinorKey() { return flags_; }
|
|
|
| void Generate(MacroAssembler* masm);
|
|
|
| - // Should the stub check whether arguments are strings?
|
| - bool string_check_;
|
| + void GenerateConvertArgument(MacroAssembler* masm,
|
| + int stack_offset,
|
| + Register arg,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + Register scratch4,
|
| + Label* slow);
|
| +
|
| + const StringAddFlags flags_;
|
| };
|
|
|
|
|
| @@ -372,7 +328,6 @@ class StringCompareStub: public CodeStub {
|
| StringCompareStub() { }
|
|
|
| // Compare two flat ASCII strings and returns result in v0.
|
| - // Does not use the stack.
|
| static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
|
| Register left,
|
| Register right,
|
| @@ -381,11 +336,28 @@ class StringCompareStub: public CodeStub {
|
| Register scratch3,
|
| Register scratch4);
|
|
|
| - private:
|
| - Major MajorKey() { return StringCompare; }
|
| - int MinorKey() { return 0; }
|
| + // Compares two flat ASCII strings for equality and returns result
|
| + // in v0.
|
| + static void GenerateFlatAsciiStringEquals(MacroAssembler* masm,
|
| + Register left,
|
| + Register right,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3);
|
|
|
| - void Generate(MacroAssembler* masm);
|
| + private:
|
| + virtual Major MajorKey() { return StringCompare; }
|
| + virtual int MinorKey() { return 0; }
|
| + virtual void Generate(MacroAssembler* masm);
|
| +
|
| + static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
|
| + Register left,
|
| + Register right,
|
| + Register length,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + Label* chars_not_equal);
|
| };
|
|
|
|
|
| @@ -485,25 +457,202 @@ class RegExpCEntryStub: public CodeStub {
|
| };
|
|
|
|
|
| -// Generate code the to load an element from a pixel array. The receiver is
|
| -// assumed to not be a smi and to have elements, the caller must guarantee this
|
| -// precondition. If the receiver does not have elements that are pixel arrays,
|
| -// the generated code jumps to not_pixel_array. If key is not a smi, then the
|
| -// generated code branches to key_not_smi. Callers can specify NULL for
|
| -// key_not_smi to signal that a smi check has already been performed on key so
|
| -// that the smi check is not generated . If key is not a valid index within the
|
| -// bounds of the pixel array, the generated code jumps to out_of_range.
|
| -void GenerateFastPixelArrayLoad(MacroAssembler* masm,
|
| - Register receiver,
|
| - Register key,
|
| - Register elements_map,
|
| - Register elements,
|
| +class FloatingPointHelper : public AllStatic {
|
| + public:
|
| +
|
| + enum Destination {
|
| + kFPURegisters,
|
| + kCoreRegisters
|
| + };
|
| +
|
| +
|
| + // Loads smis from a0 and a1 (right and left in binary operations) into
|
| + // floating point registers. Depending on the destination the values ends up
|
| + // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
|
| + // is floating point registers FPU must be supported. If core registers are
|
| + // requested when FPU is supported f12 and f14 will be scratched.
|
| + static void LoadSmis(MacroAssembler* masm,
|
| + Destination destination,
|
| + Register scratch1,
|
| + Register scratch2);
|
| +
|
| + // Loads objects from a0 and a1 (right and left in binary operations) into
|
| + // floating point registers. Depending on the destination the values ends up
|
| + // either f14 and f12 or in a2/a3 and a0/a1 respectively. If the destination
|
| + // is floating point registers FPU must be supported. If core registers are
|
| + // requested when FPU is supported f12 and f14 will still be scratched. If
|
| + // either a0 or a1 is not a number (not smi and not heap number object) the
|
| + // not_number label is jumped to with a0 and a1 intact.
|
| + static void LoadOperands(MacroAssembler* masm,
|
| + FloatingPointHelper::Destination destination,
|
| + Register heap_number_map,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* not_number);
|
| +
|
| + // Convert the smi or heap number in object to an int32 using the rules
|
| + // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
|
| + // and brought into the range -2^31 .. +2^31 - 1.
|
| + static void ConvertNumberToInt32(MacroAssembler* masm,
|
| + Register object,
|
| + Register dst,
|
| + Register heap_number_map,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + FPURegister double_scratch,
|
| + Label* not_int32);
|
| +
|
| + // Converts the integer (untagged smi) in |int_scratch| to a double, storing
|
| + // the result either in |double_dst| or |dst2:dst1|, depending on
|
| + // |destination|.
|
| + // Warning: The value in |int_scratch| will be changed in the process!
|
| + static void ConvertIntToDouble(MacroAssembler* masm,
|
| + Register int_scratch,
|
| + Destination destination,
|
| + FPURegister double_dst,
|
| + Register dst1,
|
| + Register dst2,
|
| + Register scratch2,
|
| + FPURegister single_scratch);
|
| +
|
| + // Load the number from object into double_dst in the double format.
|
| + // Control will jump to not_int32 if the value cannot be exactly represented
|
| + // by a 32-bit integer.
|
| + // Floating point value in the 32-bit integer range that are not exact integer
|
| + // won't be loaded.
|
| + static void LoadNumberAsInt32Double(MacroAssembler* masm,
|
| + Register object,
|
| + Destination destination,
|
| + FPURegister double_dst,
|
| + Register dst1,
|
| + Register dst2,
|
| + Register heap_number_map,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + FPURegister single_scratch,
|
| + Label* not_int32);
|
| +
|
| + // Loads the number from object into dst as a 32-bit integer.
|
| + // Control will jump to not_int32 if the object cannot be exactly represented
|
| + // by a 32-bit integer.
|
| + // Floating point value in the 32-bit integer range that are not exact integer
|
| + // won't be converted.
|
| + // scratch3 is not used when FPU is supported.
|
| + static void LoadNumberAsInt32(MacroAssembler* masm,
|
| + Register object,
|
| + Register dst,
|
| + Register heap_number_map,
|
| Register scratch1,
|
| Register scratch2,
|
| - Register result,
|
| - Label* not_pixel_array,
|
| - Label* key_not_smi,
|
| - Label* out_of_range);
|
| + Register scratch3,
|
| + FPURegister double_scratch,
|
| + Label* not_int32);
|
| +
|
| + // Generate non FPU code to check if a double can be exactly represented by a
|
| + // 32-bit integer. This does not check for 0 or -0, which need
|
| + // to be checked for separately.
|
| + // Control jumps to not_int32 if the value is not a 32-bit integer, and falls
|
| + // through otherwise.
|
| + // src1 and src2 will be cloberred.
|
| + //
|
| + // Expected input:
|
| + // - src1: higher (exponent) part of the double value.
|
| + // - src2: lower (mantissa) part of the double value.
|
| + // Output status:
|
| + // - dst: 32 higher bits of the mantissa. (mantissa[51:20])
|
| + // - src2: contains 1.
|
| + // - other registers are clobbered.
|
| + static void DoubleIs32BitInteger(MacroAssembler* masm,
|
| + Register src1,
|
| + Register src2,
|
| + Register dst,
|
| + Register scratch,
|
| + Label* not_int32);
|
| +
|
| + // Generates code to call a C function to do a double operation using core
|
| + // registers. (Used when FPU is not supported.)
|
| + // This code never falls through, but returns with a heap number containing
|
| + // the result in v0.
|
| + // Register heapnumber_result must be a heap number in which the
|
| + // result of the operation will be stored.
|
| + // Requires the following layout on entry:
|
| + // a0: Left value (least significant part of mantissa).
|
| + // a1: Left value (sign, exponent, top of mantissa).
|
| + // a2: Right value (least significant part of mantissa).
|
| + // a3: Right value (sign, exponent, top of mantissa).
|
| + static void CallCCodeForDoubleOperation(MacroAssembler* masm,
|
| + Token::Value op,
|
| + Register heap_number_result,
|
| + Register scratch);
|
| +
|
| + private:
|
| + static void LoadNumber(MacroAssembler* masm,
|
| + FloatingPointHelper::Destination destination,
|
| + Register object,
|
| + FPURegister dst,
|
| + Register dst1,
|
| + Register dst2,
|
| + Register heap_number_map,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Label* not_number);
|
| +};
|
| +
|
| +
|
| +class StringDictionaryLookupStub: public CodeStub {
|
| + public:
|
| + enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
|
| +
|
| + explicit StringDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
|
| +
|
| + void Generate(MacroAssembler* masm);
|
| +
|
| + static void GenerateNegativeLookup(MacroAssembler* masm,
|
| + Label* miss,
|
| + Label* done,
|
| + Register receiver,
|
| + Register properties,
|
| + String* name,
|
| + Register scratch0) ;
|
| +
|
| + static void GeneratePositiveLookup(MacroAssembler* masm,
|
| + Label* miss,
|
| + Label* done,
|
| + Register elements,
|
| + Register name,
|
| + Register r0,
|
| + Register r1);
|
| +
|
| + private:
|
| + static const int kInlinedProbes = 4;
|
| + static const int kTotalProbes = 20;
|
| +
|
| + static const int kCapacityOffset =
|
| + StringDictionary::kHeaderSize +
|
| + StringDictionary::kCapacityIndex * kPointerSize;
|
| +
|
| + static const int kElementsStartOffset =
|
| + StringDictionary::kHeaderSize +
|
| + StringDictionary::kElementsStartIndex * kPointerSize;
|
| +
|
| +
|
| +#ifdef DEBUG
|
| + void Print() {
|
| + PrintF("StringDictionaryLookupStub\n");
|
| + }
|
| +#endif
|
| +
|
| + Major MajorKey() { return StringDictionaryNegativeLookup; }
|
| +
|
| + int MinorKey() {
|
| + return LookupModeBits::encode(mode_);
|
| + }
|
| +
|
| + class LookupModeBits: public BitField<LookupMode, 0, 1> {};
|
| +
|
| + LookupMode mode_;
|
| +};
|
|
|
|
|
| } } // namespace v8::internal
|
|
|