| Index: src/ia32/stub-cache-ia32.cc
|
| diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
|
| index af53acd1705cc036694d99dfb1b8fde6b62f680a..845a4493e02f5d0f1baf9e5cf2e67bfd729939fb 100644
|
| --- a/src/ia32/stub-cache-ia32.cc
|
| +++ b/src/ia32/stub-cache-ia32.cc
|
| @@ -153,59 +153,6 @@ static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -// TODO(kmillikin): Eliminate this function when the stub cache is fully
|
| -// handlified.
|
| -static MaybeObject* TryGenerateDictionaryNegativeLookup(MacroAssembler* masm,
|
| - Label* miss_label,
|
| - Register receiver,
|
| - String* name,
|
| - Register r0,
|
| - Register r1) {
|
| - ASSERT(name->IsSymbol());
|
| - Counters* counters = masm->isolate()->counters();
|
| - __ IncrementCounter(counters->negative_lookups(), 1);
|
| - __ IncrementCounter(counters->negative_lookups_miss(), 1);
|
| -
|
| - __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset));
|
| -
|
| - const int kInterceptorOrAccessCheckNeededMask =
|
| - (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
|
| -
|
| - // Bail out if the receiver has a named interceptor or requires access checks.
|
| - __ test_b(FieldOperand(r0, Map::kBitFieldOffset),
|
| - kInterceptorOrAccessCheckNeededMask);
|
| - __ j(not_zero, miss_label);
|
| -
|
| - // Check that receiver is a JSObject.
|
| - __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
|
| - __ j(below, miss_label);
|
| -
|
| - // Load properties array.
|
| - Register properties = r0;
|
| - __ mov(properties, FieldOperand(receiver, JSObject::kPropertiesOffset));
|
| -
|
| - // Check that the properties array is a dictionary.
|
| - __ cmp(FieldOperand(properties, HeapObject::kMapOffset),
|
| - Immediate(masm->isolate()->factory()->hash_table_map()));
|
| - __ j(not_equal, miss_label);
|
| -
|
| - Label done;
|
| - MaybeObject* result =
|
| - StringDictionaryLookupStub::TryGenerateNegativeLookup(masm,
|
| - miss_label,
|
| - &done,
|
| - properties,
|
| - name,
|
| - r1);
|
| - if (result->IsFailure()) return result;
|
| -
|
| - __ bind(&done);
|
| - __ DecrementCounter(counters->negative_lookups_miss(), 1);
|
| -
|
| - return result;
|
| -}
|
| -
|
| -
|
| void StubCache::GenerateProbe(MacroAssembler* masm,
|
| Code::Flags flags,
|
| Register receiver,
|
| @@ -274,14 +221,17 @@ void StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm,
|
|
|
|
|
| void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
|
| - MacroAssembler* masm, int index, Register prototype, Label* miss) {
|
| + MacroAssembler* masm,
|
| + int index,
|
| + Register prototype,
|
| + Label* miss) {
|
| // Check we're still in the same context.
|
| __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
|
| masm->isolate()->global());
|
| __ j(not_equal, miss);
|
| // Get the global function with the given index.
|
| - JSFunction* function =
|
| - JSFunction::cast(masm->isolate()->global_context()->get(index));
|
| + Handle<JSFunction> function(
|
| + JSFunction::cast(masm->isolate()->global_context()->get(index)));
|
| // Load its initial map. The global functions all have initial maps.
|
| __ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
|
| // Load the prototype from the initial map.
|
| @@ -396,12 +346,12 @@ static void PushInterceptorArguments(MacroAssembler* masm,
|
| Register receiver,
|
| Register holder,
|
| Register name,
|
| - JSObject* holder_obj) {
|
| + Handle<JSObject> holder_obj) {
|
| __ push(name);
|
| - InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
|
| - ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor));
|
| + Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
|
| + ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor));
|
| Register scratch = name;
|
| - __ mov(scratch, Immediate(Handle<Object>(interceptor)));
|
| + __ mov(scratch, Immediate(interceptor));
|
| __ push(scratch);
|
| __ push(receiver);
|
| __ push(holder);
|
| @@ -409,11 +359,12 @@ static void PushInterceptorArguments(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -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<JSObject> holder_obj) {
|
| PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
|
| __ CallExternalReference(
|
| ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
|
| @@ -460,9 +411,9 @@ static void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) {
|
|
|
|
|
| // Generates call to API function.
|
| -static MaybeObject* GenerateFastApiCall(MacroAssembler* masm,
|
| - const CallOptimization& optimization,
|
| - int argc) {
|
| +static void GenerateFastApiCall(MacroAssembler* masm,
|
| + const CallOptimization& optimization,
|
| + int argc) {
|
| // ----------- S t a t e -------------
|
| // -- esp[0] : return address
|
| // -- esp[4] : object passing the type check
|
| @@ -477,30 +428,25 @@ static MaybeObject* GenerateFastApiCall(MacroAssembler* masm,
|
| // -- esp[(argc + 4) * 4] : receiver
|
| // -----------------------------------
|
| // Get the function and setup the context.
|
| - JSFunction* function = optimization.constant_function();
|
| - __ mov(edi, Immediate(Handle<JSFunction>(function)));
|
| + Handle<JSFunction> function = optimization.constant_function();
|
| + __ mov(edi, Immediate(function));
|
| __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
|
|
|
| // Pass the additional arguments.
|
| __ mov(Operand(esp, 2 * kPointerSize), edi);
|
| - Object* call_data = optimization.api_call_info()->data();
|
| - Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
|
| - if (masm->isolate()->heap()->InNewSpace(call_data)) {
|
| - __ mov(ecx, api_call_info_handle);
|
| + Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
|
| + Handle<Object> call_data(api_call_info->data());
|
| + if (masm->isolate()->heap()->InNewSpace(*call_data)) {
|
| + __ mov(ecx, api_call_info);
|
| __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
|
| __ mov(Operand(esp, 3 * kPointerSize), ebx);
|
| } else {
|
| - __ mov(Operand(esp, 3 * kPointerSize),
|
| - Immediate(Handle<Object>(call_data)));
|
| + __ mov(Operand(esp, 3 * kPointerSize), Immediate(call_data));
|
| }
|
|
|
| // Prepare arguments.
|
| __ lea(eax, Operand(esp, 3 * kPointerSize));
|
|
|
| - Object* callback = optimization.api_call_info()->callback();
|
| - Address api_function_address = v8::ToCData<Address>(callback);
|
| - ApiFunction fun(api_function_address);
|
| -
|
| const int kApiArgc = 1; // API function gets reference to the v8::Arguments.
|
|
|
| // Allocate the v8::Arguments structure in the arguments' space since
|
| @@ -520,12 +466,10 @@ static MaybeObject* GenerateFastApiCall(MacroAssembler* masm,
|
| __ lea(eax, ApiParameterOperand(1));
|
| __ mov(ApiParameterOperand(0), eax);
|
|
|
| - // 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.
|
| - return masm->TryCallApiFunctionAndReturn(&fun,
|
| - argc + kFastApiCallArguments + 1);
|
| + // Function address is a foreign pointer outside V8's heap.
|
| + Address function_address = v8::ToCData<Address>(api_call_info->callback());
|
| + __ CallApiFunctionAndReturn(function_address,
|
| + argc + kFastApiCallArguments + 1);
|
| }
|
|
|
|
|
| @@ -540,16 +484,16 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
| name_(name),
|
| extra_state_(extra_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<JSObject> object,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name,
|
| + LookupResult* lookup,
|
| + Register receiver,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + Label* miss) {
|
| ASSERT(holder->HasNamedInterceptor());
|
| ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
|
|
|
| @@ -557,45 +501,27 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
| __ 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(); // Success.
|
| + 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<JSObject> object,
|
| + Register receiver,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + Handle<JSObject> interceptor_holder,
|
| + LookupResult* lookup,
|
| + Handle<String> name,
|
| + const CallOptimization& optimization,
|
| + Label* miss_label) {
|
| ASSERT(optimization.is_constant_call());
|
| ASSERT(!lookup->holder()->IsGlobalObject());
|
|
|
| @@ -604,16 +530,14 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
| bool can_do_fast_api_call = false;
|
| if (optimization.is_simple_api_call() &&
|
| !lookup->holder()->IsGlobalObject()) {
|
| - depth1 =
|
| - optimization.GetPrototypeDepthOfExpectedType(object,
|
| - interceptor_holder);
|
| + depth1 = optimization.GetPrototypeDepthOfExpectedType(
|
| + object, interceptor_holder);
|
| if (depth1 == kInvalidProtoDepth) {
|
| - depth2 =
|
| - optimization.GetPrototypeDepthOfExpectedType(interceptor_holder,
|
| - lookup->holder());
|
| + depth2 = optimization.GetPrototypeDepthOfExpectedType(
|
| + interceptor_holder, Handle<JSObject>(lookup->holder()));
|
| }
|
| - can_do_fast_api_call = (depth1 != kInvalidProtoDepth) ||
|
| - (depth2 != kInvalidProtoDepth);
|
| + can_do_fast_api_call =
|
| + depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth;
|
| }
|
|
|
| Counters* counters = masm->isolate()->counters();
|
| @@ -629,9 +553,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|.
|
| @@ -644,10 +568,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<JSObject>(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
|
| @@ -658,9 +583,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
|
|
| // Invoke function.
|
| if (can_do_fast_api_call) {
|
| - MaybeObject* result =
|
| - GenerateFastApiCall(masm, optimization, arguments_.immediate());
|
| - if (result->IsFailure()) return result;
|
| + GenerateFastApiCall(masm, optimization, arguments_.immediate());
|
| } else {
|
| CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
|
| ? CALL_AS_FUNCTION
|
| @@ -681,33 +604,27 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
| if (can_do_fast_api_call) {
|
| FreeSpaceForFastApiCall(masm, scratch1);
|
| }
|
| -
|
| - return masm->isolate()->heap()->undefined_value(); // Success.
|
| }
|
|
|
| void CompileRegular(MacroAssembler* masm,
|
| - JSObject* object,
|
| + Handle<JSObject> object,
|
| Register receiver,
|
| Register scratch1,
|
| Register scratch2,
|
| Register scratch3,
|
| - String* name,
|
| - JSObject* interceptor_holder,
|
| + Handle<String> name,
|
| + Handle<JSObject> 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);
|
|
|
| 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),
|
| @@ -723,7 +640,7 @@ class CallInterceptorCompiler BASE_EMBEDDED {
|
| void LoadWithInterceptor(MacroAssembler* masm,
|
| Register receiver,
|
| Register holder,
|
| - JSObject* holder_obj,
|
| + Handle<JSObject> holder_obj,
|
| Label* interceptor_succeeded) {
|
| {
|
| FrameScope scope(masm, StackFrame::INTERNAL);
|
| @@ -762,10 +679,9 @@ void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) {
|
|
|
|
|
| void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
|
| - Code* code = masm->isolate()->builtins()->builtin(
|
| - Builtins::kKeyedLoadIC_MissForceGeneric);
|
| - Handle<Code> ic(code);
|
| - __ jmp(ic, RelocInfo::CODE_TARGET);
|
| + Handle<Code> code =
|
| + masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
|
| + __ jmp(code, RelocInfo::CODE_TARGET);
|
| }
|
|
|
|
|
| @@ -883,33 +799,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());
|
| - if (Serializer::enabled()) {
|
| - __ mov(scratch, Immediate(Handle<Object>(cell)));
|
| - __ cmp(FieldOperand(scratch, JSGlobalPropertyCell::kValueOffset),
|
| - Immediate(masm->isolate()->factory()->the_hole_value()));
|
| - } else {
|
| - __ cmp(Operand::Cell(Handle<JSGlobalPropertyCell>(cell)),
|
| - Immediate(masm->isolate()->factory()->the_hole_value()));
|
| - }
|
| - __ j(not_equal, miss);
|
| - return cell;
|
| -}
|
| -
|
| -
|
| // Calls GenerateCheckPropertyCell for each global object in the prototype chain
|
| // from object to (but not including) holder.
|
| static void GenerateCheckPropertyCells(MacroAssembler* masm,
|
| @@ -931,35 +820,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;
|
| -}
|
| -
|
| -
|
| #undef __
|
| #define __ ACCESS_MASM(masm())
|
|
|
| @@ -1076,144 +936,6 @@ Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -// TODO(kmillikin): Eliminate this function when the stub cache is fully
|
| -// handlified.
|
| -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;
|
| - JSObject* current = object;
|
| - int depth = 0;
|
| -
|
| - if (save_at_depth == depth) {
|
| - __ mov(Operand(esp, kPointerSize), reg);
|
| - }
|
| -
|
| - // Traverse the prototype chain and check the maps in the prototype chain for
|
| - // fast and global objects or do negative lookup for normal objects.
|
| - 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;
|
| - }
|
| -
|
| - __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
| - reg = holder_reg; // from now the object is in holder_reg
|
| - __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
|
| - } else if (heap()->InNewSpace(prototype)) {
|
| - // Get the map of the current object.
|
| - __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
| - __ cmp(scratch1, Immediate(Handle<Map>(current->map())));
|
| - // Branch on the result of the map check.
|
| - __ j(not_equal, miss);
|
| - // 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.
|
| - // We load the prototype from the map in the scratch register.
|
| - __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
|
| - }
|
| - // The prototype is in new space; we cannot store a reference
|
| - // to it in the code. Load it from the map.
|
| - reg = holder_reg; // from now the object is in holder_reg
|
| - __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
|
| - } else {
|
| - // Check the map of the current object.
|
| - __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
|
| - Immediate(Handle<Map>(current->map())));
|
| - // Branch on the result of the map check.
|
| - __ j(not_equal, miss);
|
| - // 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
|
| - __ mov(reg, Handle<JSObject>(prototype));
|
| - }
|
| -
|
| - if (save_at_depth == depth) {
|
| - __ mov(Operand(esp, kPointerSize), reg);
|
| - }
|
| -
|
| - // Go to the next object in the prototype chain.
|
| - current = prototype;
|
| - }
|
| - ASSERT(current == holder);
|
| -
|
| - // Log the check depth.
|
| - LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
|
| -
|
| - // Check the holder map.
|
| - __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
|
| - Immediate(Handle<Map>(holder->map())));
|
| - __ j(not_equal, miss);
|
| -
|
| - // 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<JSObject> object,
|
| Handle<JSObject> holder,
|
| Register receiver,
|
| @@ -1236,25 +958,22 @@ void StubCompiler::GenerateLoadField(Handle<JSObject> 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<JSObject> object,
|
| + Handle<JSObject> holder,
|
| + Register receiver,
|
| + Register name_reg,
|
| + Register scratch1,
|
| + Register scratch2,
|
| + Register scratch3,
|
| + Handle<AccessorInfo> callback,
|
| + Handle<String> name,
|
| + Label* miss) {
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(receiver, miss);
|
|
|
| // Check that the maps haven't changed.
|
| - Register reg =
|
| - CheckPrototypes(object, receiver, holder, scratch1,
|
| - scratch2, scratch3, name, miss);
|
| -
|
| - Handle<AccessorInfo> callback_handle(callback);
|
| + Register reg = CheckPrototypes(object, receiver, holder, scratch1,
|
| + scratch2, scratch3, name, miss);
|
|
|
| // Insert additional parameters into the stack frame above return address.
|
| ASSERT(!scratch3.is(reg));
|
| @@ -1265,11 +984,11 @@ MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
|
| ASSERT(!scratch2.is(reg));
|
| __ push(reg); // holder
|
| // Push data from AccessorInfo.
|
| - if (isolate()->heap()->InNewSpace(callback_handle->data())) {
|
| - __ mov(scratch1, Immediate(callback_handle));
|
| + if (isolate()->heap()->InNewSpace(callback->data())) {
|
| + __ mov(scratch1, Immediate(callback));
|
| __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
|
| } else {
|
| - __ push(Immediate(Handle<Object>(callback_handle->data())));
|
| + __ push(Immediate(Handle<Object>(callback->data())));
|
| }
|
|
|
| // Save a pointer to where we pushed the arguments pointer.
|
| @@ -1281,10 +1000,6 @@ MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
|
|
|
| __ push(scratch3); // Restore return address.
|
|
|
| - // Do call through the api.
|
| - Address getter_address = v8::ToCData<Address>(callback->getter());
|
| - ApiFunction fun(getter_address);
|
| -
|
| // 3 elements array for v8::Agruments::values_, handler for name and pointer
|
| // to the values (it considered as smi in GC).
|
| const int kStackSpace = 5;
|
| @@ -1299,7 +1014,8 @@ MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
|
| // already generated). Do not allow the assembler to perform a
|
| // garbage collection but instead return the allocation failure
|
| // object.
|
| - return masm()->TryCallApiFunctionAndReturn(&fun, kStackSpace);
|
| + Address getter_address = v8::ToCData<Address>(callback->getter());
|
| + __ CallApiFunctionAndReturn(getter_address, kStackSpace);
|
| }
|
|
|
|
|
| @@ -1325,15 +1041,15 @@ void StubCompiler::GenerateLoadConstant(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
| - JSObject* interceptor_holder,
|
| +void StubCompiler::GenerateLoadInterceptor(Handle<JSObject> object,
|
| + Handle<JSObject> interceptor_holder,
|
| LookupResult* lookup,
|
| Register receiver,
|
| Register name_reg,
|
| Register scratch1,
|
| Register scratch2,
|
| Register scratch3,
|
| - String* name,
|
| + Handle<String> name,
|
| Label* miss) {
|
| ASSERT(interceptor_holder->HasNamedInterceptor());
|
| ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
|
| @@ -1349,9 +1065,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;
|
| }
|
| }
|
|
|
| @@ -1405,10 +1121,10 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
|
|
| // Check that the maps from interceptor's holder to lookup's holder
|
| // haven't changed. And load lookup's holder into holder_reg.
|
| - if (interceptor_holder != lookup->holder()) {
|
| + if (*interceptor_holder != lookup->holder()) {
|
| holder_reg = CheckPrototypes(interceptor_holder,
|
| holder_reg,
|
| - lookup->holder(),
|
| + Handle<JSObject>(lookup->holder()),
|
| scratch1,
|
| scratch2,
|
| scratch3,
|
| @@ -1427,9 +1143,8 @@ 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<AccessorInfo> callback(
|
| + AccessorInfo::cast(lookup->GetCallbackObject()));
|
| ASSERT(callback->getter() != NULL);
|
|
|
| // Tail call to runtime.
|
| @@ -1438,7 +1153,7 @@ void StubCompiler::GenerateLoadInterceptor(JSObject* object,
|
| __ pop(scratch2); // return address
|
| __ push(receiver);
|
| __ push(holder_reg);
|
| - __ mov(holder_reg, Immediate(Handle<AccessorInfo>(callback)));
|
| + __ mov(holder_reg, Immediate(callback));
|
| __ push(FieldOperand(holder_reg, AccessorInfo::kDataOffset));
|
| __ push(holder_reg);
|
| __ push(name_reg);
|
| @@ -1476,9 +1191,9 @@ void CallStubCompiler::GenerateNameCheck(Handle<String> name, Label* miss) {
|
| }
|
|
|
|
|
| -void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
|
| - JSObject* holder,
|
| - String* name,
|
| +void CallStubCompiler::GenerateGlobalReceiverCheck(Handle<JSObject> object,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name,
|
| Label* miss) {
|
| ASSERT(holder->IsGlobalObject());
|
|
|
| @@ -1491,7 +1206,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(edx, miss);
|
| }
|
|
|
| @@ -1500,19 +1215,20 @@ void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object,
|
| }
|
|
|
|
|
| -void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
|
| - JSFunction* function,
|
| - Label* miss) {
|
| +void CallStubCompiler::GenerateLoadFunctionFromCell(
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Label* miss) {
|
| // Get the value from the cell.
|
| if (Serializer::enabled()) {
|
| - __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell)));
|
| + __ mov(edi, Immediate(cell));
|
| __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
|
| } else {
|
| - __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
|
| + __ mov(edi, Operand::Cell(cell));
|
| }
|
|
|
| // Check that the cell contains the same function.
|
| - if (isolate()->heap()->InNewSpace(function)) {
|
| + if (isolate()->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
|
| @@ -1525,11 +1241,10 @@ void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
|
| // Check the shared function info. Make sure it hasn't changed.
|
| __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
|
| Immediate(Handle<SharedFunctionInfo>(function->shared())));
|
| - __ j(not_equal, miss);
|
| } else {
|
| - __ cmp(edi, Immediate(Handle<JSFunction>(function)));
|
| - __ j(not_equal, miss);
|
| + __ cmp(edi, Immediate(function));
|
| }
|
| + __ j(not_equal, miss);
|
| }
|
|
|
|
|
| @@ -1542,20 +1257,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;
|
| - __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
|
| - return obj;
|
| -}
|
| -
|
| -
|
| Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
|
| Handle<JSObject> holder,
|
| int index,
|
| @@ -1612,11 +1313,12 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| - JSObject* holder,
|
| - JSGlobalPropertyCell* cell,
|
| - JSFunction* function,
|
| - String* name) {
|
| +Handle<Code> CallStubCompiler::CompileArrayPushCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -1626,13 +1328,13 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| // -----------------------------------
|
|
|
| // If object is not an array, bail out to regular call.
|
| - if (!object->IsJSArray() || cell != NULL) {
|
| - return isolate()->heap()->undefined_value();
|
| + if (!object->IsJSArray() || !cell.is_null()) {
|
| + return Handle<Code>::null();
|
| }
|
|
|
| Label miss;
|
|
|
| - GenerateNameCheck(Handle<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| @@ -1641,9 +1343,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(edx, &miss);
|
|
|
| - CheckPrototypes(JSObject::cast(object), edx,
|
| - holder, ebx,
|
| - eax, edi, name, &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
|
| + name, &miss);
|
|
|
| if (argc == 0) {
|
| // Noop, return the length.
|
| @@ -1705,8 +1406,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| FixedArray::kHeaderSize - argc * kPointerSize));
|
| __ mov(Operand(edx, 0), ecx);
|
|
|
| - __ RecordWrite(
|
| - ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
| + __ RecordWrite(ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
|
| + OMIT_SMI_CHECK);
|
|
|
| __ ret((argc + 1) * kPointerSize);
|
|
|
| @@ -1789,19 +1490,19 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
|
| }
|
|
|
| __ 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<Code> CallStubCompiler::CompileArrayPopCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -1811,13 +1512,13 @@ 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<Code>::null();
|
| }
|
|
|
| Label miss, return_undefined, call_builtin;
|
|
|
| - GenerateNameCheck(Handle<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| @@ -1825,9 +1526,8 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
|
|
|
| // Check that the receiver isn't a smi.
|
| __ JumpIfSmi(edx, &miss);
|
| - CheckPrototypes(JSObject::cast(object), edx,
|
| - holder, ebx,
|
| - eax, edi, name, &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
|
| + name, &miss);
|
|
|
| // Get the elements array of the object.
|
| __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
|
| @@ -1872,20 +1572,19 @@ MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
|
| 1);
|
|
|
| __ 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<Code> CallStubCompiler::CompileStringCharCodeAtCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : function name
|
| // -- esp[0] : return address
|
| @@ -1895,8 +1594,8 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
| // -----------------------------------
|
|
|
| // If object is not a string, bail out to regular call.
|
| - if (!object->IsString() || cell != NULL) {
|
| - return isolate()->heap()->undefined_value();
|
| + if (!object->IsString() || !cell.is_null()) {
|
| + return Handle<Code>::null();
|
| }
|
|
|
| const int argc = arguments().immediate();
|
| @@ -1912,16 +1611,16 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
| index_out_of_range_label = &miss;
|
| }
|
|
|
| - GenerateNameCheck(Handle<String>(name), &name_miss);
|
| + GenerateNameCheck(name, &name_miss);
|
|
|
| // Check that the maps starting from the prototype haven't changed.
|
| GenerateDirectLoadGlobalFunctionPrototype(masm(),
|
| Context::STRING_FUNCTION_INDEX,
|
| eax,
|
| &miss);
|
| - ASSERT(object != holder);
|
| - CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
|
| - ebx, edx, edi, name, &miss);
|
| + ASSERT(!object.is_identical_to(holder));
|
| + CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + eax, holder, ebx, edx, edi, name, &miss);
|
|
|
| Register receiver = ebx;
|
| Register index = edi;
|
| @@ -1934,19 +1633,19 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
| __ Set(index, Immediate(factory()->undefined_value()));
|
| }
|
|
|
| - 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());
|
| __ ret((argc + 1) * kPointerSize);
|
|
|
| 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);
|
| @@ -1956,22 +1655,21 @@ MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
|
|
|
| __ bind(&miss);
|
| // Restore function name in ecx.
|
| - __ Set(ecx, Immediate(Handle<String>(name)));
|
| + __ Set(ecx, Immediate(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<Code> CallStubCompiler::CompileStringCharAtCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : function name
|
| // -- esp[0] : return address
|
| @@ -1981,8 +1679,8 @@ 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<Code>::null();
|
| }
|
|
|
| const int argc = arguments().immediate();
|
| @@ -1998,16 +1696,16 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
| index_out_of_range_label = &miss;
|
| }
|
|
|
| - GenerateNameCheck(Handle<String>(name), &name_miss);
|
| + GenerateNameCheck(name, &name_miss);
|
|
|
| // Check that the maps starting from the prototype haven't changed.
|
| GenerateDirectLoadGlobalFunctionPrototype(masm(),
|
| Context::STRING_FUNCTION_INDEX,
|
| eax,
|
| &miss);
|
| - ASSERT(object != holder);
|
| - CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
|
| - ebx, edx, edi, name, &miss);
|
| + ASSERT(!object.is_identical_to(holder));
|
| + CheckPrototypes(Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + eax, holder, ebx, edx, edi, name, &miss);
|
|
|
| Register receiver = eax;
|
| Register index = edi;
|
| @@ -2021,20 +1719,20 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
| __ Set(index, Immediate(factory()->undefined_value()));
|
| }
|
|
|
| - 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());
|
| __ ret((argc + 1) * kPointerSize);
|
|
|
| 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);
|
| @@ -2044,22 +1742,21 @@ MaybeObject* CallStubCompiler::CompileStringCharAtCall(
|
|
|
| __ bind(&miss);
|
| // Restore function name in ecx.
|
| - __ Set(ecx, Immediate(Handle<String>(name)));
|
| + __ Set(ecx, Immediate(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<Code> CallStubCompiler::CompileStringFromCharCodeCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : function name
|
| // -- esp[0] : return address
|
| @@ -2073,23 +1770,22 @@ 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 isolate()->heap()->undefined_value();
|
| + return Handle<Code>::null();
|
| }
|
|
|
| Label miss;
|
| - GenerateNameCheck(Handle<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| - if (cell == NULL) {
|
| + if (cell.is_null()) {
|
| __ mov(edx, Operand(esp, 2 * kPointerSize));
|
| -
|
| STATIC_ASSERT(kSmiTag == 0);
|
| __ JumpIfSmi(edx, &miss);
|
| -
|
| - CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
|
| - &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
|
| + name, &miss);
|
| } else {
|
| - ASSERT(cell->value() == function);
|
| - GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
|
| + ASSERT(cell->value() == *function);
|
| + GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
|
| + &miss);
|
| GenerateLoadFunctionFromCell(cell, function, &miss);
|
| }
|
|
|
| @@ -2105,12 +1801,12 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
|
| // Convert the smi code to uint16.
|
| __ and_(code, Immediate(Smi::FromInt(0xffff)));
|
|
|
| - StringCharFromCodeGenerator char_from_code_generator(code, eax);
|
| - char_from_code_generator.GenerateFast(masm());
|
| + StringCharFromCodeGenerator generator(code, eax);
|
| + generator.GenerateFast(masm());
|
| __ ret(2 * kPointerSize);
|
|
|
| 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.
|
| @@ -2123,19 +1819,19 @@ MaybeObject* CallStubCompiler::CompileStringFromCharCodeCall(
|
|
|
| __ bind(&miss);
|
| // ecx: 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<Code> CallStubCompiler::CompileMathFloorCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -2145,7 +1841,7 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
|
| // -----------------------------------
|
|
|
| if (!CpuFeatures::IsSupported(SSE2)) {
|
| - return isolate()->heap()->undefined_value();
|
| + return Handle<Code>::null();
|
| }
|
|
|
| CpuFeatures::Scope use_sse2(SSE2);
|
| @@ -2155,23 +1851,24 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
|
| // 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 isolate()->heap()->undefined_value();
|
| + return Handle<Code>::null();
|
| }
|
|
|
| Label miss;
|
| - GenerateNameCheck(Handle<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| - if (cell == NULL) {
|
| + if (cell.is_null()) {
|
| __ mov(edx, Operand(esp, 2 * kPointerSize));
|
|
|
| STATIC_ASSERT(kSmiTag == 0);
|
| __ JumpIfSmi(edx, &miss);
|
|
|
| - CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
|
| - &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
|
| + name, &miss);
|
| } else {
|
| - ASSERT(cell->value() == function);
|
| - GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
|
| + ASSERT(cell->value() == *function);
|
| + GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
|
| + &miss);
|
| GenerateLoadFunctionFromCell(cell, function, &miss);
|
| }
|
|
|
| @@ -2252,19 +1949,19 @@ MaybeObject* CallStubCompiler::CompileMathFloorCall(Object* object,
|
|
|
| __ bind(&miss);
|
| // ecx: 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::CompileMathAbsCall(Object* object,
|
| - JSObject* holder,
|
| - JSGlobalPropertyCell* cell,
|
| - JSFunction* function,
|
| - String* name) {
|
| +Handle<Code> CallStubCompiler::CompileMathAbsCall(
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -2278,23 +1975,24 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
|
| // 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 isolate()->heap()->undefined_value();
|
| + return Handle<Code>::null();
|
| }
|
|
|
| Label miss;
|
| - GenerateNameCheck(Handle<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| - if (cell == NULL) {
|
| + if (cell.is_null()) {
|
| __ mov(edx, Operand(esp, 2 * kPointerSize));
|
|
|
| STATIC_ASSERT(kSmiTag == 0);
|
| __ JumpIfSmi(edx, &miss);
|
|
|
| - CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
|
| - &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
|
| + name, &miss);
|
| } else {
|
| - ASSERT(cell->value() == function);
|
| - GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
|
| + ASSERT(cell->value() == *function);
|
| + GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
|
| + &miss);
|
| GenerateLoadFunctionFromCell(cell, function, &miss);
|
| }
|
|
|
| @@ -2356,34 +2054,33 @@ MaybeObject* CallStubCompiler::CompileMathAbsCall(Object* object,
|
|
|
| __ bind(&miss);
|
| // ecx: 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<Code> CallStubCompiler::CompileFastApiCall(
|
| const CallOptimization& optimization,
|
| - Object* object,
|
| - JSObject* holder,
|
| - JSGlobalPropertyCell* cell,
|
| - JSFunction* function,
|
| - String* name) {
|
| + Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| 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<Code>::null();
|
| + if (!cell.is_null()) return Handle<Code>::null();
|
| + if (!object->IsJSObject()) return Handle<Code>::null();
|
| int depth = optimization.GetPrototypeDepthOfExpectedType(
|
| - JSObject::cast(object), holder);
|
| - if (depth == kInvalidProtoDepth) return heap()->undefined_value();
|
| + Handle<JSObject>::cast(object), holder);
|
| + if (depth == kInvalidProtoDepth) return Handle<Code>::null();
|
|
|
| Label miss, miss_before_stack_reserved;
|
|
|
| - GenerateNameCheck(Handle<String>(name), &miss_before_stack_reserved);
|
| + GenerateNameCheck(name, &miss_before_stack_reserved);
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| @@ -2401,8 +2098,8 @@ MaybeObject* CallStubCompiler::CompileFastApiCall(
|
| __ sub(esp, Immediate(kFastApiCallArguments * kPointerSize));
|
|
|
| // Check that the maps haven't changed and find a Holder as a side effect.
|
| - CheckPrototypes(JSObject::cast(object), edx, holder,
|
| - ebx, eax, edi, name, depth, &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
|
| + name, depth, &miss);
|
|
|
| // Move the return address on top of the stack.
|
| __ mov(eax, Operand(esp, 3 * kPointerSize));
|
| @@ -2410,27 +2107,24 @@ MaybeObject* CallStubCompiler::CompileFastApiCall(
|
|
|
| // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
|
| // duplicate of return address and will be overwritten.
|
| - MaybeObject* result = GenerateFastApiCall(masm(), optimization, argc);
|
| - if (result->IsFailure()) return result;
|
| + GenerateFastApiCall(masm(), optimization, argc);
|
|
|
| __ bind(&miss);
|
| __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
|
|
|
| __ 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,
|
| - CheckType check) {
|
| +Handle<Code> CallStubCompiler::CompileCallConstant(Handle<Object> object,
|
| + Handle<JSObject> holder,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name,
|
| + CheckType check) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -2440,17 +2134,15 @@ MaybeObject* CallStubCompiler::CompileCallConstant(
|
| // -----------------------------------
|
|
|
| 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> code = CompileCustomCall(object, holder,
|
| + Handle<JSGlobalPropertyCell>::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<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| // Get the receiver from the stack.
|
| const int argc = arguments().immediate();
|
| @@ -2464,15 +2156,13 @@ MaybeObject* CallStubCompiler::CompileCallConstant(
|
| // 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(isolate()->counters()->call_const(), 1);
|
|
|
| // Check that the maps haven't changed.
|
| - CheckPrototypes(JSObject::cast(object), edx, holder,
|
| - ebx, eax, edi, name, &miss);
|
| + CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax,
|
| + edi, name, &miss);
|
|
|
| // Patch the receiver on the stack with the global proxy if
|
| // necessary.
|
| @@ -2483,28 +2173,25 @@ MaybeObject* CallStubCompiler::CompileCallConstant(
|
| 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 string or a symbol.
|
| __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, eax);
|
| __ j(above_equal, &miss);
|
| // Check that the maps starting from the prototype haven't changed.
|
| GenerateDirectLoadGlobalFunctionPrototype(
|
| masm(), Context::STRING_FUNCTION_INDEX, eax, &miss);
|
| - CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
|
| - ebx, edx, edi, name, &miss);
|
| - }
|
| - break;
|
| -
|
| - case NUMBER_CHECK: {
|
| - if (!function->IsBuiltin() && !function_info->strict_mode()) {
|
| + CheckPrototypes(
|
| + Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + eax, holder, ebx, edx, edi, 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.
|
| __ JumpIfSmi(edx, &fast);
|
| @@ -2514,18 +2201,18 @@ MaybeObject* CallStubCompiler::CompileCallConstant(
|
| // Check that the maps starting from the prototype haven't changed.
|
| GenerateDirectLoadGlobalFunctionPrototype(
|
| masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
|
| - CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
|
| - ebx, edx, edi, name, &miss);
|
| - }
|
| - break;
|
| - }
|
| -
|
| - case BOOLEAN_CHECK: {
|
| - if (!function->IsBuiltin() && !function_info->strict_mode()) {
|
| + CheckPrototypes(
|
| + Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + eax, holder, ebx, edx, edi, 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.
|
| __ cmp(edx, factory()->true_value());
|
| @@ -2536,14 +2223,15 @@ MaybeObject* CallStubCompiler::CompileCallConstant(
|
| // Check that the maps starting from the prototype haven't changed.
|
| GenerateDirectLoadGlobalFunctionPrototype(
|
| masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
|
| - CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
|
| - ebx, edx, edi, name, &miss);
|
| + CheckPrototypes(
|
| + Handle<JSObject>(JSObject::cast(object->GetPrototype())),
|
| + eax, holder, ebx, edx, edi, 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_)
|
| @@ -2554,17 +2242,16 @@ MaybeObject* CallStubCompiler::CompileCallConstant(
|
|
|
| // 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<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -2574,7 +2261,7 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
| // -----------------------------------
|
| Label miss;
|
|
|
| - GenerateNameCheck(Handle<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| // Get the number of arguments.
|
| const int argc = arguments().immediate();
|
| @@ -2586,17 +2273,8 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
| __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
|
|
|
| CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state_);
|
| - MaybeObject* result = compiler.Compile(masm(),
|
| - object,
|
| - holder,
|
| - name,
|
| - &lookup,
|
| - edx,
|
| - ebx,
|
| - edi,
|
| - eax,
|
| - &miss);
|
| - if (result->IsFailure()) return result;
|
| + compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax,
|
| + &miss);
|
|
|
| // Restore receiver.
|
| __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
|
| @@ -2623,20 +2301,19 @@ MaybeObject* CallStubCompiler::CompileCallInterceptor(JSObject* object,
|
|
|
| // Handle load 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<Code> CallStubCompiler::CompileCallGlobal(
|
| + Handle<JSObject> object,
|
| + Handle<GlobalObject> holder,
|
| + Handle<JSGlobalPropertyCell> cell,
|
| + Handle<JSFunction> function,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- ecx : name
|
| // -- esp[0] : return address
|
| @@ -2646,23 +2323,17 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(
|
| // -----------------------------------
|
|
|
| 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> 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<String>(name), &miss);
|
| + GenerateNameCheck(name, &miss);
|
|
|
| // Get the number of arguments.
|
| const int argc = arguments().immediate();
|
| -
|
| GenerateGlobalReceiverCheck(object, holder, name, &miss);
|
| -
|
| GenerateLoadFunctionFromCell(cell, function, &miss);
|
|
|
| // Patch the receiver on the stack with the global proxy.
|
| @@ -2691,11 +2362,10 @@ MaybeObject* CallStubCompiler::CompileCallGlobal(
|
| // Handle call cache miss.
|
| __ bind(&miss);
|
| __ IncrementCounter(counters->call_global_inline_miss(), 1);
|
| - MaybeObject* maybe_result = TryGenerateMissBranch();
|
| - if (maybe_result->IsFailure()) return maybe_result;
|
| + GenerateMissBranch();
|
|
|
| // Return the generated code.
|
| - return TryGetCode(NORMAL, name);
|
| + return GetCode(NORMAL, name);
|
| }
|
|
|
|
|
| @@ -3039,10 +2709,11 @@ Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name,
|
| - JSObject* object,
|
| - JSObject* holder,
|
| - AccessorInfo* callback) {
|
| +Handle<Code> LoadStubCompiler::CompileLoadCallback(
|
| + Handle<String> name,
|
| + Handle<JSObject> object,
|
| + Handle<JSObject> holder,
|
| + Handle<AccessorInfo> callback) {
|
| // ----------- S t a t e -------------
|
| // -- eax : receiver
|
| // -- ecx : name
|
| @@ -3050,18 +2721,13 @@ MaybeObject* LoadStubCompiler::CompileLoadCallback(String* name,
|
| // -----------------------------------
|
| Label miss;
|
|
|
| - MaybeObject* result = GenerateLoadCallback(object, holder, eax, ecx, ebx, edx,
|
| - edi, callback, name, &miss);
|
| - if (result->IsFailure()) {
|
| - miss.Unuse();
|
| - return result;
|
| - }
|
| -
|
| + GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, edi, callback,
|
| + name, &miss);
|
| __ bind(&miss);
|
| GenerateLoadMiss(masm(), Code::LOAD_IC);
|
|
|
| // Return the generated code.
|
| - return TryGetCode(CALLBACKS, name);
|
| + return GetCode(CALLBACKS, name);
|
| }
|
|
|
|
|
| @@ -3085,9 +2751,9 @@ Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object,
|
| }
|
|
|
|
|
| -MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
| - JSObject* holder,
|
| - String* name) {
|
| +Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- eax : receiver
|
| // -- ecx : name
|
| @@ -3100,22 +2766,14 @@ MaybeObject* LoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
|
|
| // TODO(368): Compile in the whole chain: all the interceptors in
|
| // prototypes and ultimate answer.
|
| - GenerateLoadInterceptor(receiver,
|
| - holder,
|
| - &lookup,
|
| - eax,
|
| - ecx,
|
| - edx,
|
| - ebx,
|
| - edi,
|
| - name,
|
| - &miss);
|
| + GenerateLoadInterceptor(receiver, holder, &lookup, eax, ecx, edx, ebx, edi,
|
| + name, &miss);
|
|
|
| __ bind(&miss);
|
| GenerateLoadMiss(masm(), Code::LOAD_IC);
|
|
|
| // Return the generated code.
|
| - return TryGetCode(INTERCEPTOR, name);
|
| + return GetCode(INTERCEPTOR, name);
|
| }
|
|
|
|
|
| @@ -3202,11 +2860,11 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name,
|
| }
|
|
|
|
|
| -MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
|
| - String* name,
|
| - JSObject* receiver,
|
| - JSObject* holder,
|
| - AccessorInfo* callback) {
|
| +Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback(
|
| + Handle<String> name,
|
| + Handle<JSObject> receiver,
|
| + Handle<JSObject> holder,
|
| + Handle<AccessorInfo> callback) {
|
| // ----------- S t a t e -------------
|
| // -- eax : key
|
| // -- edx : receiver
|
| @@ -3218,23 +2876,18 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
|
| __ IncrementCounter(counters->keyed_load_callback(), 1);
|
|
|
| // Check that the name has not changed.
|
| - __ cmp(eax, Immediate(Handle<String>(name)));
|
| + __ cmp(eax, Immediate(name));
|
| __ j(not_equal, &miss);
|
|
|
| - MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx,
|
| - ecx, edi, callback, name, &miss);
|
| - if (result->IsFailure()) {
|
| - miss.Unuse();
|
| - return result;
|
| - }
|
| + GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx, edi, callback,
|
| + name, &miss);
|
|
|
| __ bind(&miss);
|
| -
|
| __ DecrementCounter(counters->keyed_load_callback(), 1);
|
| GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
|
|
| // Return the generated code.
|
| - return TryGetCode(CALLBACKS, name);
|
| + return GetCode(CALLBACKS, name);
|
| }
|
|
|
|
|
| @@ -3268,9 +2921,10 @@ Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant(
|
| }
|
|
|
|
|
| -MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
| - JSObject* holder,
|
| - String* name) {
|
| +Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor(
|
| + Handle<JSObject> receiver,
|
| + Handle<JSObject> holder,
|
| + Handle<String> name) {
|
| // ----------- S t a t e -------------
|
| // -- eax : key
|
| // -- edx : receiver
|
| @@ -3282,27 +2936,19 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
|
| __ IncrementCounter(counters->keyed_load_interceptor(), 1);
|
|
|
| // Check that the name has not changed.
|
| - __ cmp(eax, Immediate(Handle<String>(name)));
|
| + __ cmp(eax, Immediate(name));
|
| __ j(not_equal, &miss);
|
|
|
| LookupResult lookup(isolate());
|
| LookupPostInterceptor(holder, name, &lookup);
|
| - GenerateLoadInterceptor(receiver,
|
| - holder,
|
| - &lookup,
|
| - edx,
|
| - eax,
|
| - ecx,
|
| - ebx,
|
| - edi,
|
| - name,
|
| - &miss);
|
| + GenerateLoadInterceptor(receiver, holder, &lookup, edx, eax, ecx, ebx, edi,
|
| + name, &miss);
|
| __ bind(&miss);
|
| __ DecrementCounter(counters->keyed_load_interceptor(), 1);
|
| GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
|
|
|
| // Return the generated code.
|
| - return TryGetCode(INTERCEPTOR, name);
|
| + return GetCode(INTERCEPTOR, name);
|
| }
|
|
|
|
|
|
|