From ee3197d309c65cb514e7b7cbdb7d36b1b5ee43b1 Mon Sep 17 00:00:00 2001 From: "kmillikin@chromium.org" Date: Mon, 31 Oct 2011 12:36:11 +0000 Subject: [PATCH] MIPS: Handlify CompileConstructStub and the remaining CallStubCompiler functions. Port r9837 (38061af). Port r9834 (95ac04). Original commit message (r9834): Also, handlify functions for loading with interceptors and callbacks. Remove some unneeded code. Rename Foreign::address() because it confusingly shadows HeapObject::address() which does something quite different. BUG= TEST= Review URL: http://codereview.chromium.org/8400087 Patch from Gergely Kis . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9844 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/code-stubs-mips.cc | 89 +-- src/mips/code-stubs-mips.h | 11 - src/mips/macro-assembler-mips.cc | 64 +- src/mips/macro-assembler-mips.h | 37 +- src/mips/stub-cache-mips.cc | 1112 ++++++++++-------------------- 5 files changed, 382 insertions(+), 931 deletions(-) diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 02e1cc7c0..8ff39c529 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -5351,7 +5351,8 @@ void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { void StringCharCodeAtGenerator::GenerateSlow( - MacroAssembler* masm, const RuntimeCallHelper& call_helper) { + MacroAssembler* masm, + const RuntimeCallHelper& call_helper) { __ Abort("Unexpected fallthrough to CharCodeAt slow case"); // Index is not a smi. @@ -5437,7 +5438,8 @@ void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) { void StringCharFromCodeGenerator::GenerateSlow( - MacroAssembler* masm, const RuntimeCallHelper& call_helper) { + MacroAssembler* masm, + const RuntimeCallHelper& call_helper) { __ Abort("Unexpected fallthrough to CharFromCode slow case"); __ bind(&slow_case_); @@ -5463,7 +5465,8 @@ void StringCharAtGenerator::GenerateFast(MacroAssembler* masm) { void StringCharAtGenerator::GenerateSlow( - MacroAssembler* masm, const RuntimeCallHelper& call_helper) { + MacroAssembler* masm, + const RuntimeCallHelper& call_helper) { char_code_at_generator_.GenerateSlow(masm, call_helper); char_from_code_generator_.GenerateSlow(masm, call_helper); } @@ -7021,86 +7024,6 @@ void StringDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, } -// TODO(kmillikin): Eliminate this function when the stub cache is fully -// handlified. -MaybeObject* StringDictionaryLookupStub::TryGenerateNegativeLookup( - MacroAssembler* masm, - Label* miss, - Label* done, - Register receiver, - Register properties, - String* name, - Register scratch0) { -// If names of slots in range from 1 to kProbes - 1 for the hash value are - // not equal to the name and kProbes-th slot is not used (its name is the - // undefined value), it guarantees the hash table doesn't contain the - // property. It's true even if some slots represent deleted properties - // (their names are the null value). - for (int i = 0; i < kInlinedProbes; i++) { - // scratch0 points to properties hash. - // Compute the masked index: (hash + i + i * i) & mask. - Register index = scratch0; - // Capacity is smi 2^n. - __ lw(index, FieldMemOperand(properties, kCapacityOffset)); - __ Subu(index, index, Operand(1)); - __ And(index, index, Operand( - Smi::FromInt(name->Hash() + StringDictionary::GetProbeOffset(i)))); - - // Scale the index by multiplying by the entry size. - ASSERT(StringDictionary::kEntrySize == 3); - // index *= 3. - __ sll(at, index, 1); - __ Addu(index, index, at); - - Register entity_name = scratch0; - // Having undefined at this place means the name is not contained. - ASSERT_EQ(kSmiTagSize, 1); - Register tmp = properties; - - __ sll(scratch0, index, 1); - __ Addu(tmp, properties, scratch0); - __ lw(entity_name, FieldMemOperand(tmp, kElementsStartOffset)); - - ASSERT(!tmp.is(entity_name)); - __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex); - __ Branch(done, eq, entity_name, Operand(tmp)); - - if (i != kInlinedProbes - 1) { - // Stop if found the property. - __ Branch(miss, eq, entity_name, Operand(Handle(name))); - - // Check if the entry name is not a symbol. - __ lw(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset)); - __ lbu(entity_name, - FieldMemOperand(entity_name, Map::kInstanceTypeOffset)); - __ And(scratch0, entity_name, Operand(kIsSymbolMask)); - __ Branch(miss, eq, scratch0, Operand(zero_reg)); - - // Restore the properties. - __ lw(properties, - FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - } - } - - const int spill_mask = - (ra.bit() | t2.bit() | t1.bit() | t0.bit() | a3.bit() | - a2.bit() | a1.bit() | a0.bit() | v0.bit()); - - __ MultiPush(spill_mask); - __ lw(a0, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - __ li(a1, Operand(Handle(name))); - StringDictionaryLookupStub stub(NEGATIVE_LOOKUP); - MaybeObject* result = masm->TryCallStub(&stub); - if (result->IsFailure()) return result; - __ mov(at, v0); - __ MultiPop(spill_mask); - - __ Branch(done, eq, at, Operand(zero_reg)); - __ Branch(miss, ne, at, Operand(zero_reg)); - return result; -} - - // Probe the string dictionary in the |elements| register. Jump to the // |done| label if a property with the given name is found. Jump to // the |miss| label otherwise. diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h index beb20aab4..94ef2af54 100644 --- a/src/mips/code-stubs-mips.h +++ b/src/mips/code-stubs-mips.h @@ -807,17 +807,6 @@ class StringDictionaryLookupStub: public CodeStub { Handle name, Register scratch0); - // TODO(kmillikin): Eliminate this function when the stub cache is fully - // handlified. - MUST_USE_RESULT static MaybeObject* TryGenerateNegativeLookup( - MacroAssembler* masm, - Label* miss, - Label* done, - Register receiver, - Register properties, - String* name, - Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss, Label* done, diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index 32dce660d..36c4f4573 100644 --- a/src/mips/macro-assembler-mips.cc +++ b/src/mips/macro-assembler-mips.cc @@ -3610,7 +3610,7 @@ void MacroAssembler::InvokeFunction(Register function, } -void MacroAssembler::InvokeFunction(JSFunction* function, +void MacroAssembler::InvokeFunction(Handle function, const ParameterCount& actual, InvokeFlag flag, CallKind call_kind) { @@ -3618,7 +3618,7 @@ void MacroAssembler::InvokeFunction(JSFunction* function, ASSERT(flag == JUMP_FUNCTION || has_frame()); // Get the function and setup the context. - li(a1, Operand(Handle(function))); + li(a1, Operand(function)); lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); ParameterCount expected(function->shared()->formal_parameter_count()); @@ -3739,45 +3739,19 @@ void MacroAssembler::CallStub(CodeStub* stub, Condition cond, } -MaybeObject* MacroAssembler::TryCallStub(CodeStub* stub, Condition cond, - Register r1, const Operand& r2) { - ASSERT(AllowThisStubCall(stub)); // Stub calls are not allowed in some stubs. - Object* result; - { MaybeObject* maybe_result = stub->TryGetCode(); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - Call(Handle(Code::cast(result)), RelocInfo::CODE_TARGET, - kNoASTId, cond, r1, r2); - return result; -} - - void MacroAssembler::TailCallStub(CodeStub* stub) { ASSERT(allow_stub_calls_ || stub->CompilingCallsToThisStubIsGCSafe()); Jump(stub->GetCode(), RelocInfo::CODE_TARGET); } -MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, - Condition cond, - Register r1, - const Operand& r2) { - Object* result; - { MaybeObject* maybe_result = stub->TryGetCode(); - if (!maybe_result->ToObject(&result)) return maybe_result; - } - Jump(Handle(Code::cast(result)), RelocInfo::CODE_TARGET, cond, r1, r2); - return result; -} - - static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { return ref0.address() - ref1.address(); } -MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( - ExternalReference function, int stack_space) { +void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, + int stack_space) { ExternalReference next_address = ExternalReference::handle_scope_next_address(); const int kNextOffset = 0; @@ -3848,11 +3822,10 @@ MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( Ret(); bind(&promote_scheduled_exception); - MaybeObject* result = TryTailCallExternalReference( - ExternalReference(Runtime::kPromoteScheduledException, isolate()), 0, 1); - if (result->IsFailure()) { - return result; - } + TailCallExternalReference( + ExternalReference(Runtime::kPromoteScheduledException, isolate()), + 0, + 1); // HandleScope limit has changed. Delete allocated extensions. bind(&delete_allocated_handles); @@ -3865,8 +3838,6 @@ MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn( 1); mov(v0, s0); jmp(&leave_exit_frame); - - return result; } @@ -4089,17 +4060,6 @@ void MacroAssembler::TailCallExternalReference(const ExternalReference& ext, } -MaybeObject* MacroAssembler::TryTailCallExternalReference( - const ExternalReference& ext, int num_arguments, int result_size) { - // TODO(1236192): Most runtime routines don't need the number of - // arguments passed in because it is constant. At some point we - // should remove this need and make the runtime routine entry code - // smarter. - li(a0, num_arguments); - return TryJumpToExternalReference(ext); -} - - void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, int num_arguments, int result_size) { @@ -4116,14 +4076,6 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) { } -MaybeObject* MacroAssembler::TryJumpToExternalReference( - const ExternalReference& builtin) { - li(a1, Operand(builtin)); - CEntryStub stub(1); - return TryTailCallStub(&stub); -} - - void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, const CallWrapper& call_wrapper) { diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h index 84c55f7e6..b9bd2f3a9 100644 --- a/src/mips/macro-assembler-mips.h +++ b/src/mips/macro-assembler-mips.h @@ -812,7 +812,7 @@ class MacroAssembler: public Assembler { const CallWrapper& call_wrapper, CallKind call_kind); - void InvokeFunction(JSFunction* function, + void InvokeFunction(Handle function, const ParameterCount& actual, InvokeFlag flag, CallKind call_kind); @@ -1042,27 +1042,9 @@ class MacroAssembler: public Assembler { void CallStub(CodeStub* stub, Condition cond = cc_always, Register r1 = zero_reg, const Operand& r2 = Operand(zero_reg)); - // Call a code stub and return the code object called. Try to generate - // the code if necessary. Do not perform a GC but instead return a retry - // after GC failure. - MUST_USE_RESULT MaybeObject* TryCallStub(CodeStub* stub, - Condition cond = cc_always, - Register r1 = zero_reg, - const Operand& r2 = - Operand(zero_reg)); - // Tail call a code stub (jump). void TailCallStub(CodeStub* stub); - // Tail call a code stub (jump) and return the code object called. Try to - // generate the code if necessary. Do not perform a GC but instead return - // a retry after GC failure. - MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub, - Condition cond = cc_always, - Register r1 = zero_reg, - const Operand& r2 = - Operand(zero_reg)); - void CallJSExitStub(CodeStub* stub); // Call a runtime routine. @@ -1083,12 +1065,6 @@ class MacroAssembler: public Assembler { int num_arguments, int result_size); - // Tail call of a runtime routine (jump). Try to generate the code if - // necessary. Do not perform a GC but instead return a retry after GC - // failure. - MUST_USE_RESULT MaybeObject* TryTailCallExternalReference( - const ExternalReference& ext, int num_arguments, int result_size); - // Convenience function: tail call a runtime routine (jump). void TailCallRuntime(Runtime::FunctionId fid, int num_arguments, @@ -1139,16 +1115,15 @@ class MacroAssembler: public Assembler { void SetCallCDoubleArguments(DoubleRegister dreg1, DoubleRegister dreg2); void SetCallCDoubleArguments(DoubleRegister dreg, Register reg); - // Calls an API function. Allocates HandleScope, extracts returned value - // from handle and propagates exceptions. Restores context. - MaybeObject* TryCallApiFunctionAndReturn(ExternalReference function, - int stack_space); + // Calls an API function. Allocates HandleScope, extracts returned value + // from handle and propagates exceptions. Restores context. stack_space + // - space to be unwound on exit (includes the call js arguments space and + // the additional space allocated for the fast call). + void CallApiFunctionAndReturn(ExternalReference function, int stack_space); // Jump to the builtin routine. void JumpToExternalReference(const ExternalReference& builtin); - MaybeObject* TryJumpToExternalReference(const ExternalReference& ext); - // Invoke specified builtin JavaScript function. Adds an entry to // the unresolved list if the name does not resolve. void InvokeBuiltin(Builtins::JavaScript id, diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index 296f186e9..cb1f0929f 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -151,66 +151,6 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm, } -// TODO(kmillikin): Eliminate this function when the stub cache is fully -// handlified. -MUST_USE_RESULT static MaybeObject* TryGenerateDictionaryNegativeLookup( - MacroAssembler* masm, - Label* miss_label, - Register receiver, - String* name, - Register scratch0, - Register scratch1) { - ASSERT(name->IsSymbol()); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); - __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); - - Label done; - - const int kInterceptorOrAccessCheckNeededMask = - (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); - - // Bail out if the receiver has a named interceptor or requires access checks. - Register map = scratch1; - __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); - __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); - __ And(at, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); - __ Branch(miss_label, ne, at, Operand(zero_reg)); - - - // Check that receiver is a JSObject. - __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); - __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); - - // Load properties array. - Register properties = scratch0; - __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - // Check that the properties array is a dictionary. - __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); - Register tmp = properties; - __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); - __ Branch(miss_label, ne, map, Operand(tmp)); - - // Restore the temporarily used register. - __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - MaybeObject* result = StringDictionaryLookupStub::TryGenerateNegativeLookup( - masm, - miss_label, - &done, - receiver, - properties, - name, - scratch1); - if (result->IsFailure()) return result; - - __ bind(&done); - __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); - - return result; -} - - void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags, Register receiver, @@ -294,7 +234,10 @@ void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( - MacroAssembler* masm, int index, Register prototype, Label* miss) { + MacroAssembler* masm, + int index, + Register prototype, + Label* miss) { Isolate* isolate = masm->isolate(); // Check we're still in the same context. __ lw(prototype, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); @@ -302,8 +245,8 @@ void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( __ li(at, isolate->global()); __ Branch(miss, ne, prototype, Operand(at)); // Get the global function with the given index. - JSFunction* function = - JSFunction::cast(isolate->global_context()->get(index)); + Handle function( + JSFunction::cast(isolate->global_context()->get(index))); // Load its initial map. The global functions all have initial maps. __ li(prototype, Handle(function->initial_map())); // Load the prototype from the initial map. @@ -565,23 +508,24 @@ static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, Register holder, Register name, - JSObject* holder_obj) { + Handle holder_obj) { __ push(name); - InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); - ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor)); + Handle interceptor(holder_obj->GetNamedInterceptor()); + ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); Register scratch = name; - __ li(scratch, Operand(Handle(interceptor))); + __ li(scratch, Operand(interceptor)); __ Push(scratch, receiver, holder); __ lw(scratch, FieldMemOperand(scratch, InterceptorInfo::kDataOffset)); __ push(scratch); } -static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, - Register receiver, - Register holder, - Register name, - JSObject* holder_obj) { +static void CompileCallLoadPropertyWithInterceptor( + MacroAssembler* masm, + Register receiver, + Register holder, + Register name, + Handle holder_obj) { PushInterceptorArguments(masm, receiver, holder, name, holder_obj); ExternalReference ref = @@ -617,10 +561,9 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm) { } -static MaybeObject* GenerateFastApiDirectCall( - MacroAssembler* masm, - const CallOptimization& optimization, - int argc) { +static void GenerateFastApiDirectCall(MacroAssembler* masm, + const CallOptimization& optimization, + int argc) { // ----------- S t a t e ------------- // -- sp[0] : holder (set by CheckPrototypes) // -- sp[4] : callee js function @@ -631,18 +574,18 @@ static MaybeObject* GenerateFastApiDirectCall( // -- sp[(argc + 4) * 4] : receiver // ----------------------------------- // Get the function and setup the context. - JSFunction* function = optimization.constant_function(); - __ li(t1, Operand(Handle(function))); + Handle function = optimization.constant_function(); + __ li(t1, Operand(function)); __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); // Pass the additional arguments FastHandleApiCall expects. - Object* call_data = optimization.api_call_info()->data(); - Handle api_call_info_handle(optimization.api_call_info()); - if (masm->isolate()->heap()->InNewSpace(call_data)) { - __ li(a0, api_call_info_handle); + Handle api_call_info = optimization.api_call_info(); + Handle call_data(api_call_info->data()); + if (masm->isolate()->heap()->InNewSpace(*call_data)) { + __ li(a0, api_call_info); __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); } else { - __ li(t2, Operand(Handle(call_data))); + __ li(t2, call_data); } // Store js function and call data. @@ -653,10 +596,6 @@ static MaybeObject* GenerateFastApiDirectCall( // (refer to layout above). __ Addu(a2, sp, Operand(2 * kPointerSize)); - Object* callback = optimization.api_call_info()->callback(); - Address api_function_address = v8::ToCData
(callback); - ApiFunction fun(api_function_address); - const int kApiStackSpace = 4; FrameScope frame_scope(masm, StackFrame::MANUAL); @@ -682,17 +621,15 @@ static MaybeObject* GenerateFastApiDirectCall( // v8::Arguments::is_construct_call = 0 __ sw(zero_reg, MemOperand(a1, 3 * kPointerSize)); - // Emitting a stub call may try to allocate (if the code is not - // already generated). Do not allow the assembler to perform a - // garbage collection but instead return the allocation failure - // object. const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; + Address function_address = v8::ToCData
(api_call_info->callback()); + ApiFunction fun(function_address); ExternalReference ref = ExternalReference(&fun, ExternalReference::DIRECT_API_CALL, masm->isolate()); AllowExternalCallThatCantCauseGC scope(masm); - return masm->TryCallApiFunctionAndReturn(ref, kStackUnwindSpace); + __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); } class CallInterceptorCompiler BASE_EMBEDDED { @@ -706,86 +643,63 @@ class CallInterceptorCompiler BASE_EMBEDDED { name_(name), extra_ic_state_(extra_ic_state) {} - MaybeObject* Compile(MacroAssembler* masm, - JSObject* object, - JSObject* holder, - String* name, - LookupResult* lookup, - Register receiver, - Register scratch1, - Register scratch2, - Register scratch3, - Label* miss) { + void Compile(MacroAssembler* masm, + Handle object, + Handle holder, + Handle name, + LookupResult* lookup, + Register receiver, + Register scratch1, + Register scratch2, + Register scratch3, + Label* miss) { ASSERT(holder->HasNamedInterceptor()); ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); // Check that the receiver isn't a smi. __ JumpIfSmi(receiver, miss); - CallOptimization optimization(lookup); - if (optimization.is_constant_call()) { - return CompileCacheable(masm, - object, - receiver, - scratch1, - scratch2, - scratch3, - holder, - lookup, - name, - optimization, - miss); + CompileCacheable(masm, object, receiver, scratch1, scratch2, scratch3, + holder, lookup, name, optimization, miss); } else { - CompileRegular(masm, - object, - receiver, - scratch1, - scratch2, - scratch3, - name, - holder, - miss); - return masm->isolate()->heap()->undefined_value(); + CompileRegular(masm, object, receiver, scratch1, scratch2, scratch3, + name, holder, miss); } } private: - MaybeObject* CompileCacheable(MacroAssembler* masm, - JSObject* object, - Register receiver, - Register scratch1, - Register scratch2, - Register scratch3, - JSObject* interceptor_holder, - LookupResult* lookup, - String* name, - const CallOptimization& optimization, - Label* miss_label) { + void CompileCacheable(MacroAssembler* masm, + Handle object, + Register receiver, + Register scratch1, + Register scratch2, + Register scratch3, + Handle interceptor_holder, + LookupResult* lookup, + Handle name, + const CallOptimization& optimization, + Label* miss_label) { ASSERT(optimization.is_constant_call()); ASSERT(!lookup->holder()->IsGlobalObject()); - Counters* counters = masm->isolate()->counters(); - int depth1 = kInvalidProtoDepth; int depth2 = kInvalidProtoDepth; bool can_do_fast_api_call = false; if (optimization.is_simple_api_call() && - !lookup->holder()->IsGlobalObject()) { - depth1 = - optimization.GetPrototypeDepthOfExpectedType(object, - interceptor_holder); + !lookup->holder()->IsGlobalObject()) { + depth1 = optimization.GetPrototypeDepthOfExpectedType( + object, interceptor_holder); if (depth1 == kInvalidProtoDepth) { - depth2 = - optimization.GetPrototypeDepthOfExpectedType(interceptor_holder, - lookup->holder()); + depth2 = optimization.GetPrototypeDepthOfExpectedType( + interceptor_holder, Handle(lookup->holder())); } - can_do_fast_api_call = (depth1 != kInvalidProtoDepth) || - (depth2 != kInvalidProtoDepth); + can_do_fast_api_call = + depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth; } __ IncrementCounter(counters->call_const_interceptor(), 1, - scratch1, scratch2); + scratch1, scratch2); if (can_do_fast_api_call) { __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, @@ -798,9 +712,9 @@ class CallInterceptorCompiler BASE_EMBEDDED { Label miss_cleanup; Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; Register holder = - stub_compiler_->CheckPrototypes(object, receiver, - interceptor_holder, scratch1, - scratch2, scratch3, name, depth1, miss); + stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, + scratch1, scratch2, scratch3, + name, depth1, miss); // Invoke an interceptor and if it provides a value, // branch to |regular_invoke|. @@ -813,10 +727,11 @@ class CallInterceptorCompiler BASE_EMBEDDED { // Check that the maps from interceptor's holder to constant function's // holder haven't changed and thus we can use cached constant function. - if (interceptor_holder != lookup->holder()) { + if (*interceptor_holder != lookup->holder()) { stub_compiler_->CheckPrototypes(interceptor_holder, receiver, - lookup->holder(), scratch1, - scratch2, scratch3, name, depth2, miss); + Handle(lookup->holder()), + scratch1, scratch2, scratch3, + name, depth2, miss); } else { // CheckPrototypes has a side effect of fetching a 'holder' // for API (object which is instanceof for the signature). It's @@ -827,10 +742,7 @@ class CallInterceptorCompiler BASE_EMBEDDED { // Invoke function. if (can_do_fast_api_call) { - MaybeObject* result = GenerateFastApiDirectCall(masm, - optimization, - arguments_.immediate()); - if (result->IsFailure()) return result; + GenerateFastApiDirectCall(masm, optimization, arguments_.immediate()); } else { CallKind call_kind = CallICBase::Contextual::decode(extra_ic_state_) ? CALL_AS_FUNCTION @@ -851,68 +763,57 @@ class CallInterceptorCompiler BASE_EMBEDDED { if (can_do_fast_api_call) { FreeSpaceForFastApiCall(masm); } - - return masm->isolate()->heap()->undefined_value(); } void CompileRegular(MacroAssembler* masm, - JSObject* object, + Handle object, Register receiver, Register scratch1, Register scratch2, Register scratch3, - String* name, - JSObject* interceptor_holder, + Handle name, + Handle interceptor_holder, Label* miss_label) { Register holder = stub_compiler_->CheckPrototypes(object, receiver, interceptor_holder, - scratch1, scratch2, scratch3, name, - miss_label); + scratch1, scratch2, scratch3, + name, miss_label); // Call a runtime function to load the interceptor property. FrameScope scope(masm, StackFrame::INTERNAL); // Save the name_ register across the call. __ push(name_); - PushInterceptorArguments(masm, - receiver, - holder, - name_, - interceptor_holder); + PushInterceptorArguments(masm, receiver, holder, name_, interceptor_holder); __ CallExternalReference( ExternalReference( IC_Utility(IC::kLoadPropertyWithInterceptorForCall), masm->isolate()), 5); - // Restore the name_ register. __ pop(name_); - // Leave the internal frame. } void LoadWithInterceptor(MacroAssembler* masm, Register receiver, Register holder, - JSObject* holder_obj, + Handle holder_obj, Register scratch, Label* interceptor_succeeded) { { FrameScope scope(masm, StackFrame::INTERNAL); __ Push(holder, name_); - CompileCallLoadPropertyWithInterceptor(masm, receiver, holder, name_, holder_obj); - __ pop(name_); // Restore the name. __ pop(receiver); // Restore the holder. } - // If interceptor returns no-result sentinel, call the constant function. __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); @@ -945,29 +846,6 @@ static void GenerateCheckPropertyCell(MacroAssembler* masm, } -// TODO(kmillikin): Eliminate this function when the stub cache is fully -// handlified. -MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCell( - MacroAssembler* masm, - GlobalObject* global, - String* name, - Register scratch, - Label* miss) { - Object* probe; - { MaybeObject* maybe_probe = global->EnsurePropertyCell(name); - if (!maybe_probe->ToObject(&probe)) return maybe_probe; - } - JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(probe); - ASSERT(cell->value()->IsTheHole()); - __ li(scratch, Operand(Handle(cell))); - __ lw(scratch, - FieldMemOperand(scratch, JSGlobalPropertyCell::kValueOffset)); - __ LoadRoot(at, Heap::kTheHoleValueRootIndex); - __ Branch(miss, ne, scratch, Operand(at)); - return cell; -} - - // Calls GenerateCheckPropertyCell for each global object in the prototype chain // from object to (but not including) holder. static void GenerateCheckPropertyCells(MacroAssembler* masm, @@ -990,34 +868,6 @@ static void GenerateCheckPropertyCells(MacroAssembler* masm, } -// TODO(kmillikin): Eliminate this function when the stub cache is fully -// handlified. -MUST_USE_RESULT static MaybeObject* TryGenerateCheckPropertyCells( - MacroAssembler* masm, - JSObject* object, - JSObject* holder, - String* name, - Register scratch, - Label* miss) { - JSObject* current = object; - while (current != holder) { - if (current->IsGlobalObject()) { - // Returns a cell or a failure. - MaybeObject* result = TryGenerateCheckPropertyCell( - masm, - GlobalObject::cast(current), - name, - scratch, - miss); - if (result->IsFailure()) return result; - } - ASSERT(current->IsJSObject()); - current = JSObject::cast(current->GetPrototype()); - } - return NULL; -} - - // Convert and store int passed in register ival to IEEE 754 single precision // floating point value at memory location (dst + 4 * wordoffset) // If FPU is available use it for conversion. @@ -1240,146 +1090,6 @@ Register StubCompiler::CheckPrototypes(Handle object, } -Register StubCompiler::CheckPrototypes(JSObject* object, - Register object_reg, - JSObject* holder, - Register holder_reg, - Register scratch1, - Register scratch2, - String* name, - int save_at_depth, - Label* miss) { - // Make sure there's no overlap between holder and object registers. - ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); - ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) - && !scratch2.is(scratch1)); - - // Keep track of the current object in register reg. - Register reg = object_reg; - int depth = 0; - - if (save_at_depth == depth) { - __ sw(reg, MemOperand(sp)); - } - - // Check the maps in the prototype chain. - // Traverse the prototype chain from the object and do map checks. - JSObject* current = object; - while (current != holder) { - depth++; - - // Only global objects and objects that do not require access - // checks are allowed in stubs. - ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); - - ASSERT(current->GetPrototype()->IsJSObject()); - JSObject* prototype = JSObject::cast(current->GetPrototype()); - if (!current->HasFastProperties() && - !current->IsJSGlobalObject() && - !current->IsJSGlobalProxy()) { - if (!name->IsSymbol()) { - MaybeObject* maybe_lookup_result = heap()->LookupSymbol(name); - Object* lookup_result = NULL; // Initialization to please compiler. - if (!maybe_lookup_result->ToObject(&lookup_result)) { - set_failure(Failure::cast(maybe_lookup_result)); - return reg; - } - name = String::cast(lookup_result); - } - ASSERT(current->property_dictionary()->FindEntry(name) == - StringDictionary::kNotFound); - - MaybeObject* negative_lookup = - TryGenerateDictionaryNegativeLookup(masm(), - miss, - reg, - name, - scratch1, - scratch2); - - if (negative_lookup->IsFailure()) { - set_failure(Failure::cast(negative_lookup)); - return reg; - } - - __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - reg = holder_reg; // From now the object is in holder_reg. - __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); - } else if (heap()->InNewSpace(prototype)) { - // Get the map of the current object. - __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - - // Branch on the result of the map check. - __ Branch(miss, ne, scratch1, Operand(Handle(current->map()))); - - // Check access rights to the global object. This has to happen - // after the map check so that we know that the object is - // actually a global object. - if (current->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(reg, scratch1, miss); - // Restore scratch register to be the map of the object. In the - // new space case below, we load the prototype from the map in - // the scratch register. - __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - } - - reg = holder_reg; // From now the object is in holder_reg. - // The prototype is in new space; we cannot store a reference - // to it in the code. Load it from the map. - __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); - } else { - // Check the map of the current object. - __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - // Branch on the result of the map check. - __ Branch(miss, ne, scratch1, Operand(Handle(current->map()))); - // Check access rights to the global object. This has to happen - // after the map check so that we know that the object is - // actually a global object. - if (current->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(reg, scratch1, miss); - } - // The prototype is in old space; load it directly. - reg = holder_reg; // From now the object is in holder_reg. - __ li(reg, Operand(Handle(prototype))); - } - - if (save_at_depth == depth) { - __ sw(reg, MemOperand(sp)); - } - - // Go to the next object in the prototype chain. - current = prototype; - } - - // Check the holder map. - __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - __ Branch(miss, ne, scratch1, Operand(Handle(current->map()))); - - // Log the check depth. - LOG(masm()->isolate(), IntEvent("check-maps-depth", depth + 1)); - // Perform security check for access to the global object. - ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); - if (holder->IsJSGlobalProxy()) { - __ CheckAccessGlobalProxy(reg, scratch1, miss); - } - - // If we've skipped any global objects, it's not enough to verify - // that their maps haven't changed. We also need to check that the - // property cell for the property is still empty. - - MaybeObject* result = TryGenerateCheckPropertyCells(masm(), - object, - holder, - name, - scratch1, - miss); - if (result->IsFailure()) set_failure(Failure::cast(result)); - - // Return the register containing the holder. - return reg; -} - - void StubCompiler::GenerateLoadField(Handle object, Handle holder, Register receiver, @@ -1424,49 +1134,43 @@ void StubCompiler::GenerateLoadConstant(Handle object, } -MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, - JSObject* holder, - Register receiver, - Register name_reg, - Register scratch1, - Register scratch2, - Register scratch3, - AccessorInfo* callback, - String* name, - Label* miss) { +void StubCompiler::GenerateLoadCallback(Handle object, + Handle holder, + Register receiver, + Register name_reg, + Register scratch1, + Register scratch2, + Register scratch3, + Handle callback, + Handle name, + Label* miss) { // Check that the receiver isn't a smi. __ JumpIfSmi(receiver, miss, scratch1); // Check that the maps haven't changed. - Register reg = - CheckPrototypes(object, receiver, holder, scratch1, scratch2, scratch3, - name, miss); + Register reg = CheckPrototypes(object, receiver, holder, scratch1, + scratch2, scratch3, name, miss); // Build AccessorInfo::args_ list on the stack and push property name below // the exit frame to make GC aware of them and store pointers to them. __ push(receiver); __ mov(scratch2, sp); // scratch2 = AccessorInfo::args_ - Handle callback_handle(callback); - if (heap()->InNewSpace(callback_handle->data())) { - __ li(scratch3, callback_handle); + if (heap()->InNewSpace(callback->data())) { + __ li(scratch3, callback); __ lw(scratch3, FieldMemOperand(scratch3, AccessorInfo::kDataOffset)); } else { - __ li(scratch3, Handle(callback_handle->data())); + __ li(scratch3, Handle(callback->data())); } __ Push(reg, scratch3, name_reg); __ mov(a2, scratch2); // Saved in case scratch2 == a1. __ mov(a1, sp); // a1 (first argument - see note below) = Handle - Address getter_address = v8::ToCData
(callback->getter()); - ApiFunction fun(getter_address); - // NOTE: the O32 abi requires a0 to hold a special pointer when returning a // struct from the function (which is currently the case). This means we pass // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn // will handle setting up a0. const int kApiStackSpace = 1; - FrameScope frame_scope(masm(), StackFrame::MANUAL); __ EnterExitFrame(false, kApiStackSpace); @@ -1476,28 +1180,26 @@ MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, // a2 (second argument - see note above) = AccessorInfo& __ Addu(a2, sp, kPointerSize); - // Emitting a stub call may try to allocate (if the code is not - // already generated). Do not allow the assembler to perform a - // garbage collection but instead return the allocation failure - // object. + const int kStackUnwindSpace = 4; + Address getter_address = v8::ToCData
(callback->getter()); + ApiFunction fun(getter_address); ExternalReference ref = ExternalReference(&fun, ExternalReference::DIRECT_GETTER_CALL, masm()->isolate()); - // 4 args - will be freed later by LeaveExitFrame. - return masm()->TryCallApiFunctionAndReturn(ref, 4); + __ CallApiFunctionAndReturn(ref, kStackUnwindSpace); } -void StubCompiler::GenerateLoadInterceptor(JSObject* object, - JSObject* interceptor_holder, +void StubCompiler::GenerateLoadInterceptor(Handle object, + Handle interceptor_holder, LookupResult* lookup, Register receiver, Register name_reg, Register scratch1, Register scratch2, Register scratch3, - String* name, + Handle name, Label* miss) { ASSERT(interceptor_holder->HasNamedInterceptor()); ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); @@ -1513,9 +1215,9 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, if (lookup->type() == FIELD) { compile_followup_inline = true; } else if (lookup->type() == CALLBACKS && - lookup->GetCallbackObject()->IsAccessorInfo() && - AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL) { - compile_followup_inline = true; + lookup->GetCallbackObject()->IsAccessorInfo()) { + compile_followup_inline = + AccessorInfo::cast(lookup->GetCallbackObject())->getter() != NULL; } } @@ -1532,14 +1234,12 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, // Requires a frame to make GC aware of pushed pointers. { FrameScope frame_scope(masm(), StackFrame::INTERNAL); - if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { // CALLBACKS case needs a receiver to be passed into C++ callback. __ Push(receiver, holder_reg, name_reg); } else { __ Push(holder_reg, name_reg); } - // Invoke an interceptor. Note: map checks from receiver to // interceptor's holder has been compiled before (see a caller // of this method). @@ -1548,7 +1248,6 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, holder_reg, name_reg, interceptor_holder); - // Check if interceptor provided a value for property. If it's // the case, return immediately. Label interceptor_failed; @@ -1563,16 +1262,14 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, if (lookup->type() == CALLBACKS && !receiver.is(holder_reg)) { __ pop(receiver); } - // Leave the internal frame. } - // Check that the maps from interceptor's holder to lookup's holder // haven't changed. And load lookup's holder into |holder| register. - if (interceptor_holder != lookup->holder()) { + if (*interceptor_holder != lookup->holder()) { holder_reg = CheckPrototypes(interceptor_holder, holder_reg, - lookup->holder(), + Handle(lookup->holder()), scratch1, scratch2, scratch3, @@ -1591,15 +1288,14 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object, // We found CALLBACKS property in prototype chain of interceptor's // holder. ASSERT(lookup->type() == CALLBACKS); - ASSERT(lookup->GetCallbackObject()->IsAccessorInfo()); - AccessorInfo* callback = AccessorInfo::cast(lookup->GetCallbackObject()); - ASSERT(callback != NULL); + Handle callback( + AccessorInfo::cast(lookup->GetCallbackObject())); ASSERT(callback->getter() != NULL); // Tail call to runtime. // Important invariant in CALLBACKS case: the code above must be // structured to never clobber |receiver| register. - __ li(scratch2, Handle(callback)); + __ li(scratch2, callback); // holder_reg is either receiver or scratch1. if (!receiver.is(holder_reg)) { ASSERT(scratch1.is(holder_reg)); @@ -1642,9 +1338,9 @@ void CallStubCompiler::GenerateNameCheck(Handle name, Label* miss) { } -void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, - JSObject* holder, - String* name, +void CallStubCompiler::GenerateGlobalReceiverCheck(Handle object, + Handle holder, + Handle name, Label* miss) { ASSERT(holder->IsGlobalObject()); @@ -1657,7 +1353,7 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, // If the object is the holder then we know that it's a global // object which can only happen for contextual calls. In this case, // the receiver cannot be a smi. - if (object != holder) { + if (!object.is_identical_to(holder)) { __ JumpIfSmi(a0, miss); } @@ -1666,15 +1362,16 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, } -void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, - JSFunction* function, - Label* miss) { +void CallStubCompiler::GenerateLoadFunctionFromCell( + Handle cell, + Handle function, + Label* miss) { // Get the value from the cell. - __ li(a3, Operand(Handle(cell))); + __ li(a3, Operand(cell)); __ lw(a1, FieldMemOperand(a3, JSGlobalPropertyCell::kValueOffset)); // Check that the cell contains the same function. - if (heap()->InNewSpace(function)) { + if (heap()->InNewSpace(*function)) { // We can't embed a pointer to a function in new space so we have // to verify that the shared function info is unchanged. This has // the nice side effect that multiple closures based on the same @@ -1689,7 +1386,7 @@ void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ Branch(miss, ne, t0, Operand(a3)); } else { - __ Branch(miss, ne, a1, Operand(Handle(function))); + __ Branch(miss, ne, a1, Operand(function)); } } @@ -1703,20 +1400,6 @@ void CallStubCompiler::GenerateMissBranch() { } -// TODO(kmillikin): Eliminate this function when the stub cache is fully -// handlified. -MaybeObject* CallStubCompiler::TryGenerateMissBranch() { - MaybeObject* maybe_obj = - isolate()->stub_cache()->TryComputeCallMiss(arguments().immediate(), - kind_, - extra_state_); - Object* obj; - if (!maybe_obj->ToObject(&obj)) return maybe_obj; - __ Jump(Handle(Code::cast(obj)), RelocInfo::CODE_TARGET); - return obj; -} - - Handle CallStubCompiler::CompileCallField(Handle object, Handle holder, int index, @@ -1751,11 +1434,12 @@ Handle CallStubCompiler::CompileCallField(Handle object, } -MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileArrayPushCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : name // -- ra : return address @@ -1765,11 +1449,11 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, // ----------------------------------- // If object is not an array, bail out to regular call. - if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); + if (!object->IsJSArray() || !cell.is_null()) return Handle::null(); Label miss; - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); Register receiver = a1; @@ -1781,8 +1465,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, __ JumpIfSmi(receiver, &miss); // Check that the maps haven't changed. - CheckPrototypes(JSObject::cast(object), receiver, - holder, a3, v0, t0, name, &miss); + CheckPrototypes(Handle::cast(object), receiver, holder, a3, v0, t0, + name, &miss); if (argc == 0) { // Nothing to do, just return the length. @@ -1791,10 +1475,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, __ Ret(); } else { Label call_builtin; - Register elements = a3; Register end_elements = t1; - // Get the elements array of the object. __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); @@ -1935,19 +1617,19 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object, // Handle call cache miss. __ bind(&miss); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(function); + return GetCode(function); } -MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileArrayPopCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : name // -- ra : return address @@ -1957,25 +1639,22 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, // ----------------------------------- // If object is not an array, bail out to regular call. - if (!object->IsJSArray() || cell != NULL) return heap()->undefined_value(); + if (!object->IsJSArray() || !cell.is_null()) return Handle::null(); Label miss, return_undefined, call_builtin; - Register receiver = a1; Register elements = a3; - - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); // Get the receiver from the stack. const int argc = arguments().immediate(); __ lw(receiver, MemOperand(sp, argc * kPointerSize)); - // Check that the receiver isn't a smi. __ JumpIfSmi(receiver, &miss); // Check that the maps haven't changed. - CheckPrototypes(JSObject::cast(object), - receiver, holder, elements, t0, v0, name, &miss); + CheckPrototypes(Handle::cast(object), receiver, holder, elements, + t0, v0, name, &miss); // Get the elements array of the object. __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); @@ -2024,20 +1703,19 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, // Handle call cache miss. __ bind(&miss); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(function); + return GetCode(function); } -MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( - Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileStringCharCodeAtCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : function name // -- ra : return address @@ -2047,10 +1725,9 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( // ----------------------------------- // If object is not a string, bail out to regular call. - if (!object->IsString() || cell != NULL) return heap()->undefined_value(); + if (!object->IsString() || !cell.is_null()) return Handle::null(); const int argc = arguments().immediate(); - Label miss; Label name_miss; Label index_out_of_range; @@ -2063,16 +1740,16 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( index_out_of_range_label = &miss; } - GenerateNameCheck(Handle(name), &name_miss); + GenerateNameCheck(name, &name_miss); // Check that the maps starting from the prototype haven't changed. GenerateDirectLoadGlobalFunctionPrototype(masm(), Context::STRING_FUNCTION_INDEX, v0, &miss); - ASSERT(object != holder); - CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, - a1, a3, t0, name, &miss); + ASSERT(!object.is_identical_to(holder)); + CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), + v0, holder, a1, a3, t0, name, &miss); Register receiver = a1; Register index = t1; @@ -2085,20 +1762,20 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( __ LoadRoot(index, Heap::kUndefinedValueRootIndex); } - StringCharCodeAtGenerator char_code_at_generator(receiver, - index, - scratch, - result, - &miss, // When not a string. - &miss, // When not a number. - index_out_of_range_label, - STRING_INDEX_IS_NUMBER); - char_code_at_generator.GenerateFast(masm()); + StringCharCodeAtGenerator generator(receiver, + index, + scratch, + result, + &miss, // When not a string. + &miss, // When not a number. + index_out_of_range_label, + STRING_INDEX_IS_NUMBER); + generator.GenerateFast(masm()); __ Drop(argc + 1); __ Ret(); StubRuntimeCallHelper call_helper; - char_code_at_generator.GenerateSlow(masm(), call_helper); + generator.GenerateSlow(masm(), call_helper); if (index_out_of_range.is_linked()) { __ bind(&index_out_of_range); @@ -2109,22 +1786,21 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( __ bind(&miss); // Restore function name in a2. - __ li(a2, Handle(name)); + __ li(a2, name); __ bind(&name_miss); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(function); + return GetCode(function); } -MaybeObject* CallStubCompiler::CompileStringCharAtCall( - Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileStringCharAtCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : function name // -- ra : return address @@ -2134,31 +1810,28 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall( // ----------------------------------- // If object is not a string, bail out to regular call. - if (!object->IsString() || cell != NULL) return heap()->undefined_value(); + if (!object->IsString() || !cell.is_null()) return Handle::null(); const int argc = arguments().immediate(); - Label miss; Label name_miss; Label index_out_of_range; Label* index_out_of_range_label = &index_out_of_range; - if (kind_ == Code::CALL_IC && (CallICBase::StringStubState::decode(extra_state_) == DEFAULT_STRING_STUB)) { index_out_of_range_label = &miss; } - - GenerateNameCheck(Handle(name), &name_miss); + GenerateNameCheck(name, &name_miss); // Check that the maps starting from the prototype haven't changed. GenerateDirectLoadGlobalFunctionPrototype(masm(), Context::STRING_FUNCTION_INDEX, v0, &miss); - ASSERT(object != holder); - CheckPrototypes(JSObject::cast(object->GetPrototype()), v0, holder, - a1, a3, t0, name, &miss); + ASSERT(!object.is_identical_to(holder)); + CheckPrototypes(Handle(JSObject::cast(object->GetPrototype())), + v0, holder, a1, a3, t0, name, &miss); Register receiver = v0; Register index = t1; @@ -2172,21 +1845,21 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall( __ LoadRoot(index, Heap::kUndefinedValueRootIndex); } - StringCharAtGenerator char_at_generator(receiver, - index, - scratch1, - scratch2, - result, - &miss, // When not a string. - &miss, // When not a number. - index_out_of_range_label, - STRING_INDEX_IS_NUMBER); - char_at_generator.GenerateFast(masm()); + StringCharAtGenerator generator(receiver, + index, + scratch1, + scratch2, + result, + &miss, // When not a string. + &miss, // When not a number. + index_out_of_range_label, + STRING_INDEX_IS_NUMBER); + generator.GenerateFast(masm()); __ Drop(argc + 1); __ Ret(); StubRuntimeCallHelper call_helper; - char_at_generator.GenerateSlow(masm(), call_helper); + generator.GenerateSlow(masm(), call_helper); if (index_out_of_range.is_linked()) { __ bind(&index_out_of_range); @@ -2197,22 +1870,21 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall( __ bind(&miss); // Restore function name in a2. - __ li(a2, Handle(name)); + __ li(a2, name); __ bind(&name_miss); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(function); + return GetCode(function); } -MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( - Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileStringFromCharCodeCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : function name // -- ra : return address @@ -2225,22 +1897,23 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( // If the object is not a JSObject or we got an unexpected number of // arguments, bail out to the regular call. - if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); + if (!object->IsJSObject() || argc != 1) return Handle::null(); Label miss; - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); - if (cell == NULL) { + if (cell.is_null()) { __ lw(a1, MemOperand(sp, 1 * kPointerSize)); STATIC_ASSERT(kSmiTag == 0); __ JumpIfSmi(a1, &miss); - CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, - &miss); + CheckPrototypes(Handle::cast(object), a1, holder, v0, a3, t0, + name, &miss); } else { - ASSERT(cell->value() == function); - GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); + ASSERT(cell->value() == *function); + GenerateGlobalReceiverCheck(Handle::cast(object), holder, name, + &miss); GenerateLoadFunctionFromCell(cell, function, &miss); } @@ -2256,13 +1929,13 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( // Convert the smi code to uint16. __ And(code, code, Operand(Smi::FromInt(0xffff))); - StringCharFromCodeGenerator char_from_code_generator(code, v0); - char_from_code_generator.GenerateFast(masm()); + StringCharFromCodeGenerator generator(code, v0); + generator.GenerateFast(masm()); __ Drop(argc + 1); __ Ret(); StubRuntimeCallHelper call_helper; - char_from_code_generator.GenerateSlow(masm(), call_helper); + generator.GenerateSlow(masm(), call_helper); // Tail call the full function. We do not have to patch the receiver // because the function makes no use of it. @@ -2271,19 +1944,19 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall( __ bind(&miss); // a2: function name. - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); + return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); } -MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileMathFloorCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : function name // -- ra : return address @@ -2292,30 +1965,29 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, // -- sp[argc * 4] : receiver // ----------------------------------- - if (!CpuFeatures::IsSupported(FPU)) - return heap()->undefined_value(); - CpuFeatures::Scope scope_fpu(FPU); + if (!CpuFeatures::IsSupported(FPU)) { + return Handle::null(); + } + CpuFeatures::Scope scope_fpu(FPU); const int argc = arguments().immediate(); - // If the object is not a JSObject or we got an unexpected number of // arguments, bail out to the regular call. - if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); + if (!object->IsJSObject() || argc != 1) return Handle::null(); Label miss, slow; - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); - if (cell == NULL) { + if (cell.is_null()) { __ lw(a1, MemOperand(sp, 1 * kPointerSize)); - STATIC_ASSERT(kSmiTag == 0); __ JumpIfSmi(a1, &miss); - - CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, - &miss); + CheckPrototypes(Handle::cast(object), a1, holder, a0, a3, t0, + name, &miss); } else { - ASSERT(cell->value() == function); - GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); + ASSERT(cell->value() == *function); + GenerateGlobalReceiverCheck(Handle::cast(object), holder, name, + &miss); GenerateLoadFunctionFromCell(cell, function, &miss); } @@ -2405,19 +2077,19 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object, __ bind(&miss); // a2: function name. - MaybeObject* obj = TryGenerateMissBranch(); - if (obj->IsFailure()) return obj; + GenerateMissBranch(); // Return the generated code. - return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); + return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); } -MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileMathAbsCall( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : function name // -- ra : return address @@ -2427,25 +2099,23 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, // ----------------------------------- const int argc = arguments().immediate(); - // If the object is not a JSObject or we got an unexpected number of // arguments, bail out to the regular call. - if (!object->IsJSObject() || argc != 1) return heap()->undefined_value(); + if (!object->IsJSObject() || argc != 1) return Handle::null(); Label miss; - GenerateNameCheck(Handle(name), &miss); - if (cell == NULL) { + GenerateNameCheck(name, &miss); + if (cell.is_null()) { __ lw(a1, MemOperand(sp, 1 * kPointerSize)); - STATIC_ASSERT(kSmiTag == 0); __ JumpIfSmi(a1, &miss); - - CheckPrototypes(JSObject::cast(object), a1, holder, v0, a3, t0, name, - &miss); + CheckPrototypes(Handle::cast(object), a1, holder, v0, a3, t0, + name, &miss); } else { - ASSERT(cell->value() == function); - GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); + ASSERT(cell->value() == *function); + GenerateGlobalReceiverCheck(Handle::cast(object), holder, name, + &miss); GenerateLoadFunctionFromCell(cell, function, &miss); } @@ -2507,37 +2177,36 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object, __ bind(&miss); // a2: function name. - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return (cell == NULL) ? TryGetCode(function) : TryGetCode(NORMAL, name); + return cell.is_null() ? GetCode(function) : GetCode(NORMAL, name); } -MaybeObject* CallStubCompiler::CompileFastApiCall( +Handle CallStubCompiler::CompileFastApiCall( const CallOptimization& optimization, - Object* object, - JSObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { Counters* counters = isolate()->counters(); ASSERT(optimization.is_simple_api_call()); // Bail out if object is a global object as we don't want to // repatch it to global receiver. - if (object->IsGlobalObject()) return heap()->undefined_value(); - if (cell != NULL) return heap()->undefined_value(); - if (!object->IsJSObject()) return heap()->undefined_value(); + if (object->IsGlobalObject()) return Handle::null(); + if (!cell.is_null()) return Handle::null(); + if (!object->IsJSObject()) return Handle::null(); int depth = optimization.GetPrototypeDepthOfExpectedType( - JSObject::cast(object), holder); - if (depth == kInvalidProtoDepth) return heap()->undefined_value(); + Handle::cast(object), holder); + if (depth == kInvalidProtoDepth) return Handle::null(); Label miss, miss_before_stack_reserved; - GenerateNameCheck(Handle(name), &miss_before_stack_reserved); + GenerateNameCheck(name, &miss_before_stack_reserved); // Get the receiver from the stack. const int argc = arguments().immediate(); @@ -2552,45 +2221,42 @@ MaybeObject* CallStubCompiler::CompileFastApiCall( ReserveSpaceForFastApiCall(masm(), a0); // Check that the maps haven't changed and find a Holder as a side effect. - CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, + CheckPrototypes(Handle::cast(object), a1, holder, a0, a3, t0, name, depth, &miss); - MaybeObject* result = GenerateFastApiDirectCall(masm(), optimization, argc); - if (result->IsFailure()) return result; + GenerateFastApiDirectCall(masm(), optimization, argc); __ bind(&miss); FreeSpaceForFastApiCall(masm()); __ bind(&miss_before_stack_reserved); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(function); + return GetCode(function); } -MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, - JSObject* holder, - JSFunction* function, - String* name, +Handle CallStubCompiler::CompileCallConstant(Handle object, + Handle holder, + Handle function, + Handle name, CheckType check) { // ----------- S t a t e ------------- // -- a2 : name // -- ra : return address // ----------------------------------- if (HasCustomCallGenerator(function)) { - MaybeObject* maybe_result = CompileCustomCall( - object, holder, NULL, function, name); - Object* result; - if (!maybe_result->ToObject(&result)) return maybe_result; - // Undefined means bail out to regular compiler. - if (!result->IsUndefined()) return result; + Handle code = CompileCustomCall(object, holder, + Handle::null(), + function, name); + // A null handle means bail out to the regular compiler code below. + if (!code.is_null()) return code; } Label miss; - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); // Get the receiver from the stack. const int argc = arguments().immediate(); @@ -2605,16 +2271,14 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Make sure that it's okay not to patch the on stack receiver // unless we're doing a receiver map check. ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); - - SharedFunctionInfo* function_info = function->shared(); switch (check) { case RECEIVER_MAP_CHECK: __ IncrementCounter(masm()->isolate()->counters()->call_const(), 1, a0, a3); // Check that the maps haven't changed. - CheckPrototypes(JSObject::cast(object), a1, holder, a0, a3, t0, name, - &miss); + CheckPrototypes(Handle::cast(object), a1, holder, a0, a3, t0, + name, &miss); // Patch the receiver on the stack with the global proxy if // necessary. @@ -2625,28 +2289,25 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, break; case STRING_CHECK: - if (!function->IsBuiltin() && !function_info->strict_mode()) { - // Calling non-strict non-builtins with a value as the receiver - // requires boxing. - __ jmp(&miss); - } else { + if (function->IsBuiltin() || function->shared()->strict_mode()) { // Check that the object is a two-byte string or a symbol. __ GetObjectType(a1, a3, a3); __ Branch(&miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); // Check that the maps starting from the prototype haven't changed. GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::STRING_FUNCTION_INDEX, a0, &miss); - CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, - a1, t0, name, &miss); - } - break; - - case NUMBER_CHECK: { - if (!function->IsBuiltin() && !function_info->strict_mode()) { + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype())), + a0, holder, a3, a1, t0, name, &miss); + } else { // Calling non-strict non-builtins with a value as the receiver // requires boxing. __ jmp(&miss); - } else { + } + break; + + case NUMBER_CHECK: + if (function->IsBuiltin() || function->shared()->strict_mode()) { Label fast; // Check that the object is a smi or a heap number. __ And(t1, a1, Operand(kSmiTagMask)); @@ -2657,18 +2318,18 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Check that the maps starting from the prototype haven't changed. GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::NUMBER_FUNCTION_INDEX, a0, &miss); - CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, - a1, t0, name, &miss); - } - break; - } - - case BOOLEAN_CHECK: { - if (!function->IsBuiltin() && !function_info->strict_mode()) { + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype())), + a0, holder, a3, a1, t0, name, &miss); + } else { // Calling non-strict non-builtins with a value as the receiver // requires boxing. __ jmp(&miss); - } else { + } + break; + + case BOOLEAN_CHECK: + if (function->IsBuiltin() || function->shared()->strict_mode()) { Label fast; // Check that the object is a boolean. __ LoadRoot(t0, Heap::kTrueValueRootIndex); @@ -2679,16 +2340,17 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Check that the maps starting from the prototype haven't changed. GenerateDirectLoadGlobalFunctionPrototype( masm(), Context::BOOLEAN_FUNCTION_INDEX, a0, &miss); - CheckPrototypes(JSObject::cast(object->GetPrototype()), a0, holder, a3, - a1, t0, name, &miss); + CheckPrototypes( + Handle(JSObject::cast(object->GetPrototype())), + a0, holder, a3, a1, t0, name, &miss); + } else { + // Calling non-strict non-builtins with a value as the receiver + // requires boxing. + __ jmp(&miss); } break; } - default: - UNREACHABLE(); - } - CallKind call_kind = CallICBase::Contextual::decode(extra_state_) ? CALL_AS_FUNCTION : CALL_AS_METHOD; @@ -2697,17 +2359,16 @@ MaybeObject* CallStubCompiler::CompileCallConstant(Object* object, // Handle call cache miss. __ bind(&miss); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(function); + return GetCode(function); } -MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, - JSObject* holder, - String* name) { +Handle CallStubCompiler::CompileCallInterceptor(Handle object, + Handle holder, + Handle name) { // ----------- S t a t e ------------- // -- a2 : name // -- ra : return address @@ -2715,11 +2376,10 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, Label miss; - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); // Get the number of arguments. const int argc = arguments().immediate(); - LookupResult lookup(isolate()); LookupPostInterceptor(holder, name, &lookup); @@ -2727,64 +2387,47 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object, __ lw(a1, MemOperand(sp, argc * kPointerSize)); CallInterceptorCompiler compiler(this, arguments(), a2, extra_state_); - MaybeObject* result = compiler.Compile(masm(), - object, - holder, - name, - &lookup, - a1, - a3, - t0, - a0, - &miss); - if (result->IsFailure()) { - return result; - } + compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, + &miss); // Move returned value, the function to call, to a1. __ mov(a1, v0); // Restore receiver. __ lw(a0, MemOperand(sp, argc * kPointerSize)); - GenerateCallFunction(masm(), Handle(object), arguments(), &miss, - extra_state_); + GenerateCallFunction(masm(), object, arguments(), &miss, extra_state_); // Handle call cache miss. __ bind(&miss); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(INTERCEPTOR, name); + return GetCode(INTERCEPTOR, name); } -MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, - GlobalObject* holder, - JSGlobalPropertyCell* cell, - JSFunction* function, - String* name) { +Handle CallStubCompiler::CompileCallGlobal( + Handle object, + Handle holder, + Handle cell, + Handle function, + Handle name) { // ----------- S t a t e ------------- // -- a2 : name // -- ra : return address // ----------------------------------- if (HasCustomCallGenerator(function)) { - MaybeObject* maybe_result = CompileCustomCall( - object, holder, cell, function, name); - Object* result; - if (!maybe_result->ToObject(&result)) return maybe_result; - // Undefined means bail out to regular compiler. - if (!result->IsUndefined()) return result; + Handle code = CompileCustomCall(object, holder, cell, function, name); + // A null handle means bail out to the regular compiler code below. + if (!code.is_null()) return code; } Label miss; - - GenerateNameCheck(Handle(name), &miss); + GenerateNameCheck(name, &miss); // Get the number of arguments. const int argc = arguments().immediate(); - GenerateGlobalReceiverCheck(object, holder, name, &miss); GenerateLoadFunctionFromCell(cell, function, &miss); @@ -2801,7 +2444,6 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, // Jump to the cached code (tail call). Counters* counters = masm()->isolate()->counters(); __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); - Handle code(function->code()); ParameterCount expected(function->shared()->formal_parameter_count()); CallKind call_kind = CallICBase::Contextual::decode(extra_state_) ? CALL_AS_FUNCTION @@ -2816,11 +2458,10 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(JSObject* object, // Handle call cache miss. __ bind(&miss); __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); - MaybeObject* maybe_result = TryGenerateMissBranch(); - if (maybe_result->IsFailure()) return maybe_result; + GenerateMissBranch(); // Return the generated code. - return TryGetCode(NORMAL, name); + return GetCode(NORMAL, name); } @@ -3053,29 +2694,24 @@ Handle LoadStubCompiler::CompileLoadField(Handle object, } -MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name, - JSObject* object, - JSObject* holder, - AccessorInfo* callback) { +Handle LoadStubCompiler::CompileLoadCallback( + Handle name, + Handle object, + Handle holder, + Handle callback) { // ----------- S t a t e ------------- // -- a0 : receiver // -- a2 : name // -- ra : return address // ----------------------------------- Label miss; - - MaybeObject* result = GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, - callback, name, &miss); - if (result->IsFailure()) { - miss.Unuse(); - return result; - } - + GenerateLoadCallback(object, holder, a0, a2, a3, a1, t0, callback, name, + &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return TryGetCode(CALLBACKS, name); + return GetCode(CALLBACKS, name); } @@ -3099,9 +2735,9 @@ Handle LoadStubCompiler::CompileLoadConstant(Handle object, } -MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, - JSObject* holder, - String* name) { +Handle LoadStubCompiler::CompileLoadInterceptor(Handle object, + Handle holder, + Handle name) { // ----------- S t a t e ------------- // -- a0 : receiver // -- a2 : name @@ -3112,21 +2748,13 @@ MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* object, LookupResult lookup(isolate()); LookupPostInterceptor(holder, name, &lookup); - GenerateLoadInterceptor(object, - holder, - &lookup, - a0, - a2, - a3, - a1, - t0, - name, + GenerateLoadInterceptor(object, holder, &lookup, a0, a2, a3, a1, t0, name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::LOAD_IC); // Return the generated code. - return TryGetCode(INTERCEPTOR, name); + return GetCode(INTERCEPTOR, name); } @@ -3200,11 +2828,11 @@ Handle KeyedLoadStubCompiler::CompileLoadField(Handle name, } -MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( - String* name, - JSObject* receiver, - JSObject* holder, - AccessorInfo* callback) { +Handle KeyedLoadStubCompiler::CompileLoadCallback( + Handle name, + Handle receiver, + Handle holder, + Handle callback) { // ----------- S t a t e ------------- // -- ra : return address // -- a0 : key @@ -3213,19 +2841,14 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( Label miss; // Check the key is the cached one. - __ Branch(&miss, ne, a0, Operand(Handle(name))); - - MaybeObject* result = GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, - t0, callback, name, &miss); - if (result->IsFailure()) { - miss.Unuse(); - return result; - } + __ Branch(&miss, ne, a0, Operand(name)); + GenerateLoadCallback(receiver, holder, a1, a0, a2, a3, t0, callback, name, + &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return TryGetCode(CALLBACKS, name); + return GetCode(CALLBACKS, name); } @@ -3253,9 +2876,10 @@ Handle KeyedLoadStubCompiler::CompileLoadConstant( } -MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, - JSObject* holder, - String* name) { +Handle KeyedLoadStubCompiler::CompileLoadInterceptor( + Handle receiver, + Handle holder, + Handle name) { // ----------- S t a t e ------------- // -- ra : return address // -- a0 : key @@ -3264,24 +2888,16 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, Label miss; // Check the key is the cached one. - __ Branch(&miss, ne, a0, Operand(Handle(name))); + __ Branch(&miss, ne, a0, Operand(name)); LookupResult lookup(isolate()); LookupPostInterceptor(holder, name, &lookup); - GenerateLoadInterceptor(receiver, - holder, - &lookup, - a1, - a0, - a2, - a3, - t0, - name, + GenerateLoadInterceptor(receiver, holder, &lookup, a1, a0, a2, a3, t0, name, &miss); __ bind(&miss); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); - return TryGetCode(INTERCEPTOR, name); + return GetCode(INTERCEPTOR, name); } @@ -3496,7 +3112,8 @@ Handle KeyedStoreStubCompiler::CompileStorePolymorphic( } -MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { +Handle ConstructStubCompiler::CompileConstructStub( + Handle function) { // a0 : argc // a1 : constructor // ra : return address @@ -3541,12 +3158,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { // a2: initial map // t7: undefined __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset)); - __ AllocateInNewSpace(a3, - t4, - t5, - t6, - &generic_stub_call, - SIZE_IN_WORDS); + __ AllocateInNewSpace(a3, t4, t5, t6, &generic_stub_call, SIZE_IN_WORDS); // Allocated the JSObject, now initialize the fields. Map is set to initial // map and properties and elements are set to empty fixed array. @@ -3581,7 +3193,7 @@ MaybeObject* ConstructStubCompiler::CompileConstructStub(JSFunction* function) { // t7: undefined // Fill the initialized properties with a constant value or a passed argument // depending on the this.x = ...; assignment in the function. - SharedFunctionInfo* shared = function->shared(); + Handle shared(function->shared()); for (int i = 0; i < shared->this_property_assignments_count(); i++) { if (shared->IsThisPropertyAssignmentArgument(i)) { Label not_passed, next; @@ -4053,9 +3665,9 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); __ bind(&miss_force_generic); - Code* stub = masm->isolate()->builtins()->builtin( - Builtins::kKeyedLoadIC_MissForceGeneric); - __ Jump(Handle(stub), RelocInfo::CODE_TARGET); + Handle stub = + masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); + __ Jump(stub, RelocInfo::CODE_TARGET); } @@ -4483,9 +4095,9 @@ void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { __ Ret(); __ bind(&miss_force_generic); - Code* stub = masm->isolate()->builtins()->builtin( - Builtins::kKeyedLoadIC_MissForceGeneric); - __ Jump(Handle(stub), RelocInfo::CODE_TARGET); + Handle stub = + masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); + __ Jump(stub, RelocInfo::CODE_TARGET); } -- 2.34.1