diff options
Diffstat (limited to 'deps/v8/src/ic/arm/handler-compiler-arm.cc')
-rw-r--r-- | deps/v8/src/ic/arm/handler-compiler-arm.cc | 163 |
1 files changed, 37 insertions, 126 deletions
diff --git a/deps/v8/src/ic/arm/handler-compiler-arm.cc b/deps/v8/src/ic/arm/handler-compiler-arm.cc index a3f23d3f22..4ed765e73f 100644 --- a/deps/v8/src/ic/arm/handler-compiler-arm.cc +++ b/deps/v8/src/ic/arm/handler-compiler-arm.cc @@ -203,9 +203,11 @@ void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( void PropertyHandlerCompiler::GenerateCheckPropertyCell( MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, Register scratch, Label* miss) { - Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); - DCHECK(cell->value()->IsTheHole()); - Handle<WeakCell> weak_cell = masm->isolate()->factory()->NewWeakCell(cell); + Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( + global, name, PropertyCellType::kInvalidated); + Isolate* isolate = masm->isolate(); + DCHECK(cell->value()->IsTheHole(isolate)); + Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); __ LoadWeakValue(scratch, weak_cell, miss); __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); @@ -290,7 +292,7 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); bool call_data_undefined = false; // Put call data in place. - if (api_call_info->data()->IsUndefined()) { + if (api_call_info->data()->IsUndefined(isolate)) { call_data_undefined = true; __ LoadRoot(data, Heap::kUndefinedValueRootIndex); } else { @@ -332,17 +334,8 @@ void PropertyHandlerCompiler::GenerateApiAccessorCall( static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), StoreDescriptor::ValueRegister(), - VectorStoreICDescriptor::SlotRegister(), - VectorStoreICDescriptor::VectorRegister()); -} - - -void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // The slow case calls into the runtime to complete the store without causing - // an IC miss that would otherwise cause a transition to the generic stub. - __ TailCallRuntime(Runtime::kStoreIC_Slow); + StoreWithVectorDescriptor::SlotRegister(), + StoreWithVectorDescriptor::VectorRegister()); } @@ -437,28 +430,25 @@ Register PropertyHandlerCompiler::CheckPrototypes( DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && !scratch2.is(scratch1)); - if (FLAG_eliminate_prototype_chain_checks) { - Handle<Cell> validity_cell = - Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); - if (!validity_cell.is_null()) { - DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), - validity_cell->value()); - __ mov(scratch1, Operand(validity_cell)); - __ ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); - __ cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid))); - __ b(ne, miss); - } + Handle<Cell> validity_cell = + Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); + if (!validity_cell.is_null()) { + DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); + __ mov(scratch1, Operand(validity_cell)); + __ ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); + __ cmp(scratch1, Operand(Smi::FromInt(Map::kPrototypeChainValid))); + __ b(ne, miss); + } - // The prototype chain of primitives (and their JSValue wrappers) depends - // on the native context, which can't be guarded by validity cells. - // |object_reg| holds the native context specific prototype in this case; - // we need to check its map. - if (check == CHECK_ALL_MAPS) { - __ ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset)); - Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); - __ CmpWeakValue(scratch1, cell, scratch2); - __ b(ne, miss); - } + // The prototype chain of primitives (and their JSValue wrappers) depends + // on the native context, which can't be guarded by validity cells. + // |object_reg| holds the native context specific prototype in this case; + // we need to check its map. + if (check == CHECK_ALL_MAPS) { + __ ldr(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset)); + Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); + __ CmpWeakValue(scratch1, cell, scratch2); + __ b(ne, miss); } // Keep track of the current object in register reg. @@ -494,8 +484,10 @@ Register PropertyHandlerCompiler::CheckPrototypes( !current_map->is_access_check_needed()); prototype = handle(JSObject::cast(current_map->prototype())); - if (current_map->is_dictionary_map() && - !current_map->IsJSGlobalObjectMap()) { + if (current_map->IsJSGlobalObjectMap()) { + GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), + name, scratch2, miss); + } else if (current_map->is_dictionary_map()) { DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. if (!name->IsUniqueName()) { DCHECK(name->IsString()); @@ -505,33 +497,12 @@ Register PropertyHandlerCompiler::CheckPrototypes( current->property_dictionary()->FindEntry(name) == NameDictionary::kNotFound); - if (FLAG_eliminate_prototype_chain_checks && depth > 1) { + if (depth > 1) { // TODO(jkummerow): Cache and re-use weak cell. __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss); } GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, scratch2); - if (!FLAG_eliminate_prototype_chain_checks) { - __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - __ ldr(holder_reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); - } - } else { - Register map_reg = scratch1; - if (!FLAG_eliminate_prototype_chain_checks) { - __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); - } - if (current_map->IsJSGlobalObjectMap()) { - GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), - name, scratch2, miss); - } else if (!FLAG_eliminate_prototype_chain_checks && - (depth != 1 || check == CHECK_ALL_MAPS)) { - Handle<WeakCell> cell = Map::WeakCellForMap(current_map); - __ CmpWeakValue(map_reg, cell, scratch2); - __ b(ne, miss); - } - if (!FLAG_eliminate_prototype_chain_checks) { - __ ldr(holder_reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); - } } reg = holder_reg; // From now on the object will be in holder_reg. @@ -545,17 +516,8 @@ Register PropertyHandlerCompiler::CheckPrototypes( // Log the check depth. LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); - if (!FLAG_eliminate_prototype_chain_checks && - (depth != 0 || check == CHECK_ALL_MAPS)) { - // Check the holder map. - __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); - Handle<WeakCell> cell = Map::WeakCellForMap(current_map); - __ CmpWeakValue(scratch1, cell, scratch2); - __ b(ne, miss); - } - bool return_holder = return_what == RETURN_HOLDER; - if (FLAG_eliminate_prototype_chain_checks && return_holder && depth != 0) { + if (return_holder && depth != 0) { __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss); } @@ -597,61 +559,10 @@ void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { __ Ret(); } - -void NamedLoadHandlerCompiler::GenerateLoadCallback( - Register reg, Handle<AccessorInfo> callback) { - DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), receiver())); - DCHECK(!AreAliased(scratch2(), scratch3(), scratch4(), reg)); - - // Build v8::PropertyCallbackInfo::args_ array on the stack and push property - // name below the exit frame to make GC aware of them. - STATIC_ASSERT(PropertyCallbackArguments::kShouldThrowOnErrorIndex == 0); - STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 1); - STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 2); - STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 3); - STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 4); - STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 5); - STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 6); - STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 7); - - __ push(receiver()); - // Push data from AccessorInfo. - Handle<Object> data(callback->data(), isolate()); - if (data->IsUndefined() || data->IsSmi()) { - __ Move(scratch2(), data); - } else { - Handle<WeakCell> cell = - isolate()->factory()->NewWeakCell(Handle<HeapObject>::cast(data)); - // The callback is alive if this instruction is executed, - // so the weak cell is not cleared and points to data. - __ GetWeakValue(scratch2(), cell); - } - __ push(scratch2()); - __ LoadRoot(scratch2(), Heap::kUndefinedValueRootIndex); - __ Push(scratch2(), scratch2()); - __ mov(scratch2(), Operand(ExternalReference::isolate_address(isolate()))); - __ Push(scratch2(), reg); - __ Push(Smi::FromInt(0)); // should_throw_on_error -> false - __ push(name()); - - // Abi for CallApiGetter - Register getter_address_reg = ApiGetterDescriptor::function_address(); - - Address getter_address = v8::ToCData<Address>(callback->getter()); - ApiFunction fun(getter_address); - ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; - ExternalReference ref = ExternalReference(&fun, type, isolate()); - __ mov(getter_address_reg, Operand(ref)); - - CallApiGetterStub stub(isolate()); - __ TailCallStub(&stub); -} - - void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( LookupIterator* it, Register holder_reg) { DCHECK(holder()->HasNamedInterceptor()); - DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); + DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); // Compile the interceptor call, followed by inline code to load the // property from further up the prototype chain if the call fails. @@ -711,7 +622,7 @@ void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { // Call the runtime system to load the interceptor. DCHECK(holder()->HasNamedInterceptor()); - DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); + DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), holder()); @@ -729,7 +640,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( // If the callback cannot leak, then push the callback directly, // otherwise wrap it in a weak cell. - if (callback->data()->IsUndefined() || callback->data()->IsSmi()) { + if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) { __ mov(ip, Operand(callback)); } else { Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); @@ -744,7 +655,7 @@ Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( __ TailCallRuntime(Runtime::kStoreCallbackProperty); // Return the generated code. - return GetCode(kind(), Code::FAST, name); + return GetCode(kind(), name); } @@ -784,7 +695,7 @@ Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( FrontendFooter(name, &miss); // Return the generated code. - return GetCode(kind(), Code::NORMAL, name); + return GetCode(kind(), name); } |