• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env ruby
2
3# Copyright (c) 2021-2022 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 = $temps_mask + :arg0 + :arg1
19
20AllocateObjectTlabValidation = {
21  spills_count_max: 2,  # TODO(msherstennikov): set to 0 once regalloc supports smart temps
22  code_size_max: { arm64: 108, x86_64: 460, arm32: 9999 }
23  # TODO(msherstennikov): revert back code size values, once regalloc supports smart temps
24  # code_size_max: { arm64: 100, x86_64: 125, arm32: 9999 }
25}
26
27AllocateArrayTlabValidation = {
28  spills_count_max: 2,  # TODO(msherstennikov): set to 0 once regalloc supports smart temps
29  code_size_max: { arm64: 136, x86_64: 476, arm32: 9999 }
30  # TODO(msherstennikov): revert back code size values, once regalloc supports smart temps
31  # code_size_max: { arm64: 128, x86_64: 145, arm32: 9999 }
32}
33
34function(:AllocateObjectTlab,
35         params: {klass: 'ref', size: 'word'},
36         regmap: $full_regmap,
37         mode: [:FastPath],
38         regalloc_set: $available_regs,
39         validate: AllocateObjectTlabValidation) {
40
41  if Options.arch == :arm32
42    Intrinsic(:UNREACHABLE).void
43    ReturnVoid()
44    next
45  end
46
47  # Load pointer to the TLAB from TLS
48  tlab_ptr := LoadI(%tr).Imm(Constants::TLAB_OFFSET).ptr
49
50  # Load pointer to the start address of free memory in the TLAB
51  start := LoadI(tlab_ptr).Imm(Constants::TLAB_CUR_FREE_POSITION_OFFSET).ptr
52
53  # Load pointer to the end address of free memory in the TLAB
54  tls_end := LoadI(tlab_ptr).Imm(Constants::TLAB_MEMORY_END_ADDR_OFFSET).ptr
55
56  tls_size := Sub(tls_end, start).word
57
58  If(tls_size, size).CC(:CC_LT).b {
59    Intrinsic(:SLOW_PATH_ENTRY, klass, size).AddImm(Constants::CREATE_OBJECT_BY_CLASS).ptr
60    Intrinsic(:UNREACHABLE).void if defines.DEBUG
61  } Else {
62    call_runtime_save_all(Constants::WRITE_TLAB_STATS_NO_BRIDGE, size).void if defines.DEBUG
63    if defines.__SANITIZE_ADDRESS__ || defines.__SANITIZE_THREAD__
64      call_runtime_save_all(Constants::ANNOTATE_SANITIZERS_NO_BRIDGE, start, size).void
65    end
66    new_start := Add(start, size).ptr
67    StoreI(start, klass).Imm(Constants::OBJECT_CLASS_OFFSET).ref
68    addr := Add(tlab_ptr, Constants::TLAB_CUR_FREE_POSITION_OFFSET).ptr
69    StoreI(addr, new_start).Imm(0).Volatile.ptr
70    Return(start).ptr
71  }
72}
73
74# Allow three temps, two arguments registers and one callee saved register
75$available_regs = $available_regs + :callee0
76
77def AllocateArrayTlab(element_size)
78  function("AllocateArrayTlab#{element_size}".to_sym,
79           params: {klass: 'ref', elements_num: 'word'},
80           regmap: $full_regmap,
81           mode: [:FastPath],
82           regalloc_set: $available_regs,
83           validate: AllocateArrayTlabValidation) {
84    if Options.arch == :arm32
85      ReturnVoid()
86      next
87    end
88
89    if element_size == 8
90      size := elements_num
91    elsif element_size == 16
92      size := Shl(elements_num, 1).word
93    elsif element_size == 32
94      size := Shl(elements_num, 2).word
95    elsif element_size == 64
96      size := Shl(elements_num, 3).word
97    else
98      raise "Wrong element size #{element_size}"
99    end
100    # Add sizeof(Array) and do align
101    size := Add(size, "DEFAULT_ALIGNMENT_IN_BYTES - 1 + CORETYPES_ARRAY_CLASS_SIZE").word
102    size := And(size, "~(DEFAULT_ALIGNMENT_IN_BYTES - 1)").word
103
104    # Load pointer to the TLAB from TLS
105    tlab_ptr := LoadI(%tr).Imm(Constants::TLAB_OFFSET).ptr
106
107    # Load pointer to the start address of free memory in the TLAB
108    start := LoadI(tlab_ptr).Imm(Constants::TLAB_CUR_FREE_POSITION_OFFSET).ptr
109
110    # Load pointer to the end address of free memory in the TLAB
111    tls_end := LoadI(tlab_ptr).Imm(Constants::TLAB_MEMORY_END_ADDR_OFFSET).ptr
112
113    tls_size := Sub(tls_end, start).word
114
115    If(tls_size, size).CC(:CC_LT).b {
116      Intrinsic(:SLOW_PATH_ENTRY, klass, elements_num).AddImm(Constants::CREATE_ARRAY_SLOW_PATH).ptr
117      Intrinsic(:UNREACHABLE).void if defines.DEBUG
118    } Else {
119      call_runtime_save_all(Constants::WRITE_TLAB_STATS_NO_BRIDGE, size).void if defines.DEBUG
120      if defines.__SANITIZE_ADDRESS__ || defines.__SANITIZE_THREAD__
121        call_runtime_save_all(Constants::ANNOTATE_SANITIZERS_NO_BRIDGE, start, size).void
122      end
123      new_start := Add(start, size).ptr
124      StoreI(start, klass).Imm(Constants::OBJECT_CLASS_OFFSET).ref
125      StoreI(start, elements_num).Imm(Constants::ARRAY_LENGTH_OFFSET).ref
126      addr := Add(tlab_ptr, Constants::TLAB_CUR_FREE_POSITION_OFFSET).ptr
127      StoreI(addr, new_start).Imm(0).Volatile.ptr
128      Return(start).ptr
129    }
130  }
131end
132
133AllocateArrayTlab(8)
134AllocateArrayTlab(16)
135AllocateArrayTlab(32)
136AllocateArrayTlab(64)
137