diff options
Diffstat (limited to 'deps/v8/src/mips/code-stubs-mips.cc')
-rw-r--r-- | deps/v8/src/mips/code-stubs-mips.cc | 126 |
1 files changed, 57 insertions, 69 deletions
diff --git a/deps/v8/src/mips/code-stubs-mips.cc b/deps/v8/src/mips/code-stubs-mips.cc index 1b3242cf09..f3dd95b851 100644 --- a/deps/v8/src/mips/code-stubs-mips.cc +++ b/deps/v8/src/mips/code-stubs-mips.cc @@ -481,7 +481,7 @@ void ConvertToDoubleStub::Generate(MacroAssembler* masm) { __ Branch(¬_special, gt, source_, Operand(1)); // For 1 or -1 we need to or in the 0 exponent (biased to 1023). - static const uint32_t exponent_word_for_1 = + const uint32_t exponent_word_for_1 = HeapNumber::kExponentBias << HeapNumber::kExponentShift; // Safe to use 'at' as dest reg here. __ Or(at, exponent, Operand(exponent_word_for_1)); @@ -2754,7 +2754,6 @@ void BinaryOpStub::GenerateSmiCode( Register left = a1; Register right = a0; Register scratch1 = t3; - Register scratch2 = t5; // Perform combined smi check on both operands. __ Or(scratch1, left, Operand(right)); @@ -3459,7 +3458,6 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { Label no_update; Label skip_cache; - const Register heap_number_map = t2; // Call C function to calculate the result and update the cache. // Register a0 holds precalculated cache entry address; preserve @@ -4421,7 +4419,7 @@ Register InstanceofStub::right() { return a1; } void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { // The displacement is the offset of the last parameter (if any) // relative to the frame pointer. - static const int kDisplacement = + const int kDisplacement = StandardFrameConstants::kCallerSPOffset - kPointerSize; // Check that the key is a smiGenerateReadElement. @@ -4833,10 +4831,10 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { // sp[8]: subject string // sp[12]: JSRegExp object - static const int kLastMatchInfoOffset = 0 * kPointerSize; - static const int kPreviousIndexOffset = 1 * kPointerSize; - static const int kSubjectOffset = 2 * kPointerSize; - static const int kJSRegExpOffset = 3 * kPointerSize; + const int kLastMatchInfoOffset = 0 * kPointerSize; + const int kPreviousIndexOffset = 1 * kPointerSize; + const int kSubjectOffset = 2 * kPointerSize; + const int kJSRegExpOffset = 3 * kPointerSize; Isolate* isolate = masm->isolate(); @@ -5045,8 +5043,8 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { 1, a0, a2); // Isolates: note we add an additional parameter here (isolate pointer). - static const int kRegExpExecuteArguments = 8; - static const int kParameterRegisters = 4; + const int kRegExpExecuteArguments = 8; + const int kParameterRegisters = 4; __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters); // Stack pointer now points to cell where return address is to be written. @@ -5402,9 +5400,9 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { __ LoadRoot(at, Heap::kTheHoleValueRootIndex); __ Branch(&call, ne, t0, Operand(at)); // Patch the receiver on the stack with the global receiver object. - __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); - __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); - __ sw(a2, MemOperand(sp, argc_ * kPointerSize)); + __ lw(a3, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); + __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset)); + __ sw(a3, MemOperand(sp, argc_ * kPointerSize)); __ bind(&call); } @@ -5412,8 +5410,12 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // a1: pushed function (to be verified) __ JumpIfSmi(a1, &non_function); // Get the map of the function object. - __ GetObjectType(a1, a2, a2); - __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE)); + __ GetObjectType(a1, a3, a3); + __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE)); + + if (RecordCallTarget()) { + GenerateRecordCallTarget(masm); + } // Fast-case: Invoke the function now. // a1: pushed function @@ -5438,8 +5440,17 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { // Slow-case: Non-function called. __ bind(&slow); + if (RecordCallTarget()) { + // If there is a call target cache, mark it megamorphic in the + // non-function case. MegamorphicSentinel is an immortal immovable + // object (undefined) so no write barrier is needed. + ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), + masm->isolate()->heap()->undefined_value()); + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ sw(at, FieldMemOperand(a2, JSGlobalPropertyCell::kValueOffset)); + } // Check for function proxy. - __ Branch(&non_function, ne, a2, Operand(JS_FUNCTION_PROXY_TYPE)); + __ Branch(&non_function, ne, a3, Operand(JS_FUNCTION_PROXY_TYPE)); __ push(a1); // Put proxy as additional argument. __ li(a0, Operand(argc_ + 1, RelocInfo::NONE)); __ li(a2, Operand(0, RelocInfo::NONE)); @@ -5931,7 +5942,7 @@ void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, // scratch: - // Perform a number of probes in the symbol table. - static const int kProbes = 4; + const int kProbes = 4; Label found_in_symbol_table; Label next_probe[kProbes]; Register candidate = scratch5; // Scratch register contains candidate. @@ -6059,9 +6070,9 @@ void SubStringStub::Generate(MacroAssembler* masm) { // 0 <= from <= to <= string.length. // If any of these assumptions fail, we call the runtime system. - static const int kToOffset = 0 * kPointerSize; - static const int kFromOffset = 1 * kPointerSize; - static const int kStringOffset = 2 * kPointerSize; + const int kToOffset = 0 * kPointerSize; + const int kFromOffset = 1 * kPointerSize; + const int kStringOffset = 2 * kPointerSize; __ lw(a2, MemOperand(sp, kToOffset)); __ lw(a3, MemOperand(sp, kFromOffset)); @@ -6095,37 +6106,11 @@ void SubStringStub::Generate(MacroAssembler* masm) { // a2: result string length __ lw(t0, FieldMemOperand(v0, String::kLengthOffset)); __ sra(t0, t0, 1); + // Return original string. __ Branch(&return_v0, eq, a2, Operand(t0)); - - - Label result_longer_than_two; - // Check for special case of two character ASCII string, in which case - // we do a lookup in the symbol table first. - __ li(t0, 2); - __ Branch(&result_longer_than_two, gt, a2, Operand(t0)); - __ Branch(&runtime, lt, a2, Operand(t0)); - - __ JumpIfInstanceTypeIsNotSequentialAscii(a1, a1, &runtime); - - // Get the two characters forming the sub string. - __ Addu(v0, v0, Operand(a3)); - __ lbu(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); - __ lbu(t0, FieldMemOperand(v0, SeqAsciiString::kHeaderSize + 1)); - - // Try to lookup two character string in symbol table. - Label make_two_character_string; - StringHelper::GenerateTwoCharacterSymbolTableProbe( - masm, a3, t0, a1, t1, t2, t3, t4, &make_two_character_string); - __ jmp(&return_v0); - - // a2: result string length. - // a3: two characters combined into halfword in little endian byte order. - __ bind(&make_two_character_string); - __ AllocateAsciiString(v0, a2, t0, t1, t4, &runtime); - __ sh(a3, FieldMemOperand(v0, SeqAsciiString::kHeaderSize)); - __ jmp(&return_v0); - - __ bind(&result_longer_than_two); + // Longer than original string's length or negative: unsafe arguments. + __ Branch(&runtime, hi, a2, Operand(t0)); + // Shorter than original string's length: an actual substring. // Deal with different string types: update the index if necessary // and put the underlying string into t1. @@ -7356,43 +7341,46 @@ struct AheadOfTimeWriteBarrierStubList { RememberedSetAction action; }; +#define REG(Name) { kRegister_ ## Name ## _Code } -struct AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { +static const AheadOfTimeWriteBarrierStubList kAheadOfTime[] = { // Used in RegExpExecStub. - { s2, s0, t3, EMIT_REMEMBERED_SET }, - { s2, a2, t3, EMIT_REMEMBERED_SET }, + { REG(s2), REG(s0), REG(t3), EMIT_REMEMBERED_SET }, + { REG(s2), REG(a2), REG(t3), EMIT_REMEMBERED_SET }, // Used in CompileArrayPushCall. // Also used in StoreIC::GenerateNormal via GenerateDictionaryStore. // Also used in KeyedStoreIC::GenerateGeneric. - { a3, t0, t1, EMIT_REMEMBERED_SET }, + { REG(a3), REG(t0), REG(t1), EMIT_REMEMBERED_SET }, // Used in CompileStoreGlobal. - { t0, a1, a2, OMIT_REMEMBERED_SET }, + { REG(t0), REG(a1), REG(a2), OMIT_REMEMBERED_SET }, // Used in StoreStubCompiler::CompileStoreField via GenerateStoreField. - { a1, a2, a3, EMIT_REMEMBERED_SET }, - { a3, a2, a1, EMIT_REMEMBERED_SET }, + { REG(a1), REG(a2), REG(a3), EMIT_REMEMBERED_SET }, + { REG(a3), REG(a2), REG(a1), EMIT_REMEMBERED_SET }, // Used in KeyedStoreStubCompiler::CompileStoreField via GenerateStoreField. - { a2, a1, a3, EMIT_REMEMBERED_SET }, - { a3, a1, a2, EMIT_REMEMBERED_SET }, + { REG(a2), REG(a1), REG(a3), EMIT_REMEMBERED_SET }, + { REG(a3), REG(a1), REG(a2), EMIT_REMEMBERED_SET }, // KeyedStoreStubCompiler::GenerateStoreFastElement. - { a3, a2, t0, EMIT_REMEMBERED_SET }, - { a2, a3, t0, EMIT_REMEMBERED_SET }, + { REG(a3), REG(a2), REG(t0), EMIT_REMEMBERED_SET }, + { REG(a2), REG(a3), REG(t0), EMIT_REMEMBERED_SET }, // ElementsTransitionGenerator::GenerateSmiOnlyToObject // and ElementsTransitionGenerator::GenerateSmiOnlyToDouble // and ElementsTransitionGenerator::GenerateDoubleToObject - { a2, a3, t5, EMIT_REMEMBERED_SET }, - { a2, a3, t5, OMIT_REMEMBERED_SET }, + { REG(a2), REG(a3), REG(t5), EMIT_REMEMBERED_SET }, + { REG(a2), REG(a3), REG(t5), OMIT_REMEMBERED_SET }, // ElementsTransitionGenerator::GenerateDoubleToObject - { t2, a2, a0, EMIT_REMEMBERED_SET }, - { a2, t2, t5, EMIT_REMEMBERED_SET }, + { REG(t2), REG(a2), REG(a0), EMIT_REMEMBERED_SET }, + { REG(a2), REG(t2), REG(t5), EMIT_REMEMBERED_SET }, // StoreArrayLiteralElementStub::Generate - { t1, a0, t2, EMIT_REMEMBERED_SET }, + { REG(t1), REG(a0), REG(t2), EMIT_REMEMBERED_SET }, // Null termination. - { no_reg, no_reg, no_reg, EMIT_REMEMBERED_SET} + { REG(no_reg), REG(no_reg), REG(no_reg), EMIT_REMEMBERED_SET} }; +#undef REG + bool RecordWriteStub::IsPregenerated() { - for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; + for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; !entry->object.is(no_reg); entry++) { if (object_.is(entry->object) && @@ -7419,7 +7407,7 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime() { void RecordWriteStub::GenerateFixedRegStubsAheadOfTime() { - for (AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; + for (const AheadOfTimeWriteBarrierStubList* entry = kAheadOfTime; !entry->object.is(no_reg); entry++) { RecordWriteStub stub(entry->object, |