• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env ruby
2
3# Copyright (c) 2021-2024 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16include_relative 'common.irt'
17
18$available_regs = RegMask.new($full_regmap, :tmp1, :arg0, :arg1, :callee0, :callee2, :callee3)
19if Options.arch == :arm64
20  $available_regs = $available_regs + :callee1
21else
22  $available_regs = $available_regs + :tmp2
23end
24
25function(:CheckCastInterfaceEntrypoint,
26          params: {obj: 'ptr', interface: 'ptr'},
27          regmap: $full_regmap,
28          regalloc_set: $available_regs,
29          mode: [:FastPath]) {
30    if Options.arch == :arm32
31        Intrinsic(:UNREACHABLE).Terminator.void
32        next
33    end
34
35    klass := load_class(obj)
36    size := LoadI(klass).Imm(Constants::CLASS_ITABLE_ENTRIES_SIZE_OFFSET).word
37    elements0 := LoadI(klass).Imm(Constants::CLASS_ITABLE_ENTRIES_DATA_OFFSET).ptr
38    i0 := 0
39Label(:Loop)
40    elements_phi := Phi(elements0, elements1).ptr
41    i_phi := Phi(i0, i1).word
42    If(i_phi, size).EQ.Unlikely {
43        Goto(:SlowPath)
44    }
45    implemented_interface := LoadI(elements_phi).Imm(Constants::CLASS_ITABLE_ENTRY_INTERFACE_OFFSET).ptr
46    If(implemented_interface, interface).EQ.Unlikely.b {
47        ReturnVoid().void
48    }
49    elements1 := Add(elements_phi, Constants::CLASS_ITABLE_ENTRY_SIZE).ptr
50    i1 := Add(i_phi, 1).word
51    Goto(:Loop)
52Label(:SlowPath)
53    ep_offset = get_entrypoint_offset("CHECK_CAST_SLOW_PATH")
54    Intrinsic(:SLOW_PATH_ENTRY, obj, interface).AddImm(ep_offset).MethodAsImm("CheckCastBridge").Terminator.void
55    Intrinsic(:UNREACHABLE).Terminator.void if defines.DEBUG
56}
57