diff options
206 files changed, 2612 insertions, 3055 deletions
diff --git a/benchmark/Android.bp b/benchmark/Android.bp index dd198889e9..014a2b3372 100644 --- a/benchmark/Android.bp +++ b/benchmark/Android.bp @@ -17,7 +17,7 @@ art_cc_library { name: "libartbenchmark", host_supported: true, - defaults: ["art_defaults", "art_debug_defaults"], + defaults: ["art_defaults" ], srcs: [ "jni_loader.cc", "jobject-benchmark/jobject_benchmark.cc", diff --git a/benchmark/const-string/info.txt b/benchmark/const-string/info.txt new file mode 100644 index 0000000000..78f39d246f --- /dev/null +++ b/benchmark/const-string/info.txt @@ -0,0 +1 @@ +Benchmarks for repeating const-string instructions in a loop. diff --git a/benchmark/const-string/src/ConstStringBenchmark.java b/benchmark/const-string/src/ConstStringBenchmark.java new file mode 100644 index 0000000000..2beb0a4c60 --- /dev/null +++ b/benchmark/const-string/src/ConstStringBenchmark.java @@ -0,0 +1,1066 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +public class ConstStringBenchmark { + // Initialize 1025 strings with consecutive string indexes in the dex file. + // The tests below rely on the knowledge that ART uses the low 10 bits + // of the string index as the hash into DexCache strings array. + public static final String string_0000 = "TestString_0000"; + public static final String string_0001 = "TestString_0001"; + public static final String string_0002 = "TestString_0002"; + public static final String string_0003 = "TestString_0003"; + public static final String string_0004 = "TestString_0004"; + public static final String string_0005 = "TestString_0005"; + public static final String string_0006 = "TestString_0006"; + public static final String string_0007 = "TestString_0007"; + public static final String string_0008 = "TestString_0008"; + public static final String string_0009 = "TestString_0009"; + public static final String string_0010 = "TestString_0010"; + public static final String string_0011 = "TestString_0011"; + public static final String string_0012 = "TestString_0012"; + public static final String string_0013 = "TestString_0013"; + public static final String string_0014 = "TestString_0014"; + public static final String string_0015 = "TestString_0015"; + public static final String string_0016 = "TestString_0016"; + public static final String string_0017 = "TestString_0017"; + public static final String string_0018 = "TestString_0018"; + public static final String string_0019 = "TestString_0019"; + public static final String string_0020 = "TestString_0020"; + public static final String string_0021 = "TestString_0021"; + public static final String string_0022 = "TestString_0022"; + public static final String string_0023 = "TestString_0023"; + public static final String string_0024 = "TestString_0024"; + public static final String string_0025 = "TestString_0025"; + public static final String string_0026 = "TestString_0026"; + public static final String string_0027 = "TestString_0027"; + public static final String string_0028 = "TestString_0028"; + public static final String string_0029 = "TestString_0029"; + public static final String string_0030 = "TestString_0030"; + public static final String string_0031 = "TestString_0031"; + public static final String string_0032 = "TestString_0032"; + public static final String string_0033 = "TestString_0033"; + public static final String string_0034 = "TestString_0034"; + public static final String string_0035 = "TestString_0035"; + public static final String string_0036 = "TestString_0036"; + public static final String string_0037 = "TestString_0037"; + public static final String string_0038 = "TestString_0038"; + public static final String string_0039 = "TestString_0039"; + public static final String string_0040 = "TestString_0040"; + public static final String string_0041 = "TestString_0041"; + public static final String string_0042 = "TestString_0042"; + public static final String string_0043 = "TestString_0043"; + public static final String string_0044 = "TestString_0044"; + public static final String string_0045 = "TestString_0045"; + public static final String string_0046 = "TestString_0046"; + public static final String string_0047 = "TestString_0047"; + public static final String string_0048 = "TestString_0048"; + public static final String string_0049 = "TestString_0049"; + public static final String string_0050 = "TestString_0050"; + public static final String string_0051 = "TestString_0051"; + public static final String string_0052 = "TestString_0052"; + public static final String string_0053 = "TestString_0053"; + public static final String string_0054 = "TestString_0054"; + public static final String string_0055 = "TestString_0055"; + public static final String string_0056 = "TestString_0056"; + public static final String string_0057 = "TestString_0057"; + public static final String string_0058 = "TestString_0058"; + public static final String string_0059 = "TestString_0059"; + public static final String string_0060 = "TestString_0060"; + public static final String string_0061 = "TestString_0061"; + public static final String string_0062 = "TestString_0062"; + public static final String string_0063 = "TestString_0063"; + public static final String string_0064 = "TestString_0064"; + public static final String string_0065 = "TestString_0065"; + public static final String string_0066 = "TestString_0066"; + public static final String string_0067 = "TestString_0067"; + public static final String string_0068 = "TestString_0068"; + public static final String string_0069 = "TestString_0069"; + public static final String string_0070 = "TestString_0070"; + public static final String string_0071 = "TestString_0071"; + public static final String string_0072 = "TestString_0072"; + public static final String string_0073 = "TestString_0073"; + public static final String string_0074 = "TestString_0074"; + public static final String string_0075 = "TestString_0075"; + public static final String string_0076 = "TestString_0076"; + public static final String string_0077 = "TestString_0077"; + public static final String string_0078 = "TestString_0078"; + public static final String string_0079 = "TestString_0079"; + public static final String string_0080 = "TestString_0080"; + public static final String string_0081 = "TestString_0081"; + public static final String string_0082 = "TestString_0082"; + public static final String string_0083 = "TestString_0083"; + public static final String string_0084 = "TestString_0084"; + public static final String string_0085 = "TestString_0085"; + public static final String string_0086 = "TestString_0086"; + public static final String string_0087 = "TestString_0087"; + public static final String string_0088 = "TestString_0088"; + public static final String string_0089 = "TestString_0089"; + public static final String string_0090 = "TestString_0090"; + public static final String string_0091 = "TestString_0091"; + public static final String string_0092 = "TestString_0092"; + public static final String string_0093 = "TestString_0093"; + public static final String string_0094 = "TestString_0094"; + public static final String string_0095 = "TestString_0095"; + public static final String string_0096 = "TestString_0096"; + public static final String string_0097 = "TestString_0097"; + public static final String string_0098 = "TestString_0098"; + public static final String string_0099 = "TestString_0099"; + public static final String string_0100 = "TestString_0100"; + public static final String string_0101 = "TestString_0101"; + public static final String string_0102 = "TestString_0102"; + public static final String string_0103 = "TestString_0103"; + public static final String string_0104 = "TestString_0104"; + public static final String string_0105 = "TestString_0105"; + public static final String string_0106 = "TestString_0106"; + public static final String string_0107 = "TestString_0107"; + public static final String string_0108 = "TestString_0108"; + public static final String string_0109 = "TestString_0109"; + public static final String string_0110 = "TestString_0110"; + public static final String string_0111 = "TestString_0111"; + public static final String string_0112 = "TestString_0112"; + public static final String string_0113 = "TestString_0113"; + public static final String string_0114 = "TestString_0114"; + public static final String string_0115 = "TestString_0115"; + public static final String string_0116 = "TestString_0116"; + public static final String string_0117 = "TestString_0117"; + public static final String string_0118 = "TestString_0118"; + public static final String string_0119 = "TestString_0119"; + public static final String string_0120 = "TestString_0120"; + public static final String string_0121 = "TestString_0121"; + public static final String string_0122 = "TestString_0122"; + public static final String string_0123 = "TestString_0123"; + public static final String string_0124 = "TestString_0124"; + public static final String string_0125 = "TestString_0125"; + public static final String string_0126 = "TestString_0126"; + public static final String string_0127 = "TestString_0127"; + public static final String string_0128 = "TestString_0128"; + public static final String string_0129 = "TestString_0129"; + public static final String string_0130 = "TestString_0130"; + public static final String string_0131 = "TestString_0131"; + public static final String string_0132 = "TestString_0132"; + public static final String string_0133 = "TestString_0133"; + public static final String string_0134 = "TestString_0134"; + public static final String string_0135 = "TestString_0135"; + public static final String string_0136 = "TestString_0136"; + public static final String string_0137 = "TestString_0137"; + public static final String string_0138 = "TestString_0138"; + public static final String string_0139 = "TestString_0139"; + public static final String string_0140 = "TestString_0140"; + public static final String string_0141 = "TestString_0141"; + public static final String string_0142 = "TestString_0142"; + public static final String string_0143 = "TestString_0143"; + public static final String string_0144 = "TestString_0144"; + public static final String string_0145 = "TestString_0145"; + public static final String string_0146 = "TestString_0146"; + public static final String string_0147 = "TestString_0147"; + public static final String string_0148 = "TestString_0148"; + public static final String string_0149 = "TestString_0149"; + public static final String string_0150 = "TestString_0150"; + public static final String string_0151 = "TestString_0151"; + public static final String string_0152 = "TestString_0152"; + public static final String string_0153 = "TestString_0153"; + public static final String string_0154 = "TestString_0154"; + public static final String string_0155 = "TestString_0155"; + public static final String string_0156 = "TestString_0156"; + public static final String string_0157 = "TestString_0157"; + public static final String string_0158 = "TestString_0158"; + public static final String string_0159 = "TestString_0159"; + public static final String string_0160 = "TestString_0160"; + public static final String string_0161 = "TestString_0161"; + public static final String string_0162 = "TestString_0162"; + public static final String string_0163 = "TestString_0163"; + public static final String string_0164 = "TestString_0164"; + public static final String string_0165 = "TestString_0165"; + public static final String string_0166 = "TestString_0166"; + public static final String string_0167 = "TestString_0167"; + public static final String string_0168 = "TestString_0168"; + public static final String string_0169 = "TestString_0169"; + public static final String string_0170 = "TestString_0170"; + public static final String string_0171 = "TestString_0171"; + public static final String string_0172 = "TestString_0172"; + public static final String string_0173 = "TestString_0173"; + public static final String string_0174 = "TestString_0174"; + public static final String string_0175 = "TestString_0175"; + public static final String string_0176 = "TestString_0176"; + public static final String string_0177 = "TestString_0177"; + public static final String string_0178 = "TestString_0178"; + public static final String string_0179 = "TestString_0179"; + public static final String string_0180 = "TestString_0180"; + public static final String string_0181 = "TestString_0181"; + public static final String string_0182 = "TestString_0182"; + public static final String string_0183 = "TestString_0183"; + public static final String string_0184 = "TestString_0184"; + public static final String string_0185 = "TestString_0185"; + public static final String string_0186 = "TestString_0186"; + public static final String string_0187 = "TestString_0187"; + public static final String string_0188 = "TestString_0188"; + public static final String string_0189 = "TestString_0189"; + public static final String string_0190 = "TestString_0190"; + public static final String string_0191 = "TestString_0191"; + public static final String string_0192 = "TestString_0192"; + public static final String string_0193 = "TestString_0193"; + public static final String string_0194 = "TestString_0194"; + public static final String string_0195 = "TestString_0195"; + public static final String string_0196 = "TestString_0196"; + public static final String string_0197 = "TestString_0197"; + public static final String string_0198 = "TestString_0198"; + public static final String string_0199 = "TestString_0199"; + public static final String string_0200 = "TestString_0200"; + public static final String string_0201 = "TestString_0201"; + public static final String string_0202 = "TestString_0202"; + public static final String string_0203 = "TestString_0203"; + public static final String string_0204 = "TestString_0204"; + public static final String string_0205 = "TestString_0205"; + public static final String string_0206 = "TestString_0206"; + public static final String string_0207 = "TestString_0207"; + public static final String string_0208 = "TestString_0208"; + public static final String string_0209 = "TestString_0209"; + public static final String string_0210 = "TestString_0210"; + public static final String string_0211 = "TestString_0211"; + public static final String string_0212 = "TestString_0212"; + public static final String string_0213 = "TestString_0213"; + public static final String string_0214 = "TestString_0214"; + public static final String string_0215 = "TestString_0215"; + public static final String string_0216 = "TestString_0216"; + public static final String string_0217 = "TestString_0217"; + public static final String string_0218 = "TestString_0218"; + public static final String string_0219 = "TestString_0219"; + public static final String string_0220 = "TestString_0220"; + public static final String string_0221 = "TestString_0221"; + public static final String string_0222 = "TestString_0222"; + public static final String string_0223 = "TestString_0223"; + public static final String string_0224 = "TestString_0224"; + public static final String string_0225 = "TestString_0225"; + public static final String string_0226 = "TestString_0226"; + public static final String string_0227 = "TestString_0227"; + public static final String string_0228 = "TestString_0228"; + public static final String string_0229 = "TestString_0229"; + public static final String string_0230 = "TestString_0230"; + public static final String string_0231 = "TestString_0231"; + public static final String string_0232 = "TestString_0232"; + public static final String string_0233 = "TestString_0233"; + public static final String string_0234 = "TestString_0234"; + public static final String string_0235 = "TestString_0235"; + public static final String string_0236 = "TestString_0236"; + public static final String string_0237 = "TestString_0237"; + public static final String string_0238 = "TestString_0238"; + public static final String string_0239 = "TestString_0239"; + public static final String string_0240 = "TestString_0240"; + public static final String string_0241 = "TestString_0241"; + public static final String string_0242 = "TestString_0242"; + public static final String string_0243 = "TestString_0243"; + public static final String string_0244 = "TestString_0244"; + public static final String string_0245 = "TestString_0245"; + public static final String string_0246 = "TestString_0246"; + public static final String string_0247 = "TestString_0247"; + public static final String string_0248 = "TestString_0248"; + public static final String string_0249 = "TestString_0249"; + public static final String string_0250 = "TestString_0250"; + public static final String string_0251 = "TestString_0251"; + public static final String string_0252 = "TestString_0252"; + public static final String string_0253 = "TestString_0253"; + public static final String string_0254 = "TestString_0254"; + public static final String string_0255 = "TestString_0255"; + public static final String string_0256 = "TestString_0256"; + public static final String string_0257 = "TestString_0257"; + public static final String string_0258 = "TestString_0258"; + public static final String string_0259 = "TestString_0259"; + public static final String string_0260 = "TestString_0260"; + public static final String string_0261 = "TestString_0261"; + public static final String string_0262 = "TestString_0262"; + public static final String string_0263 = "TestString_0263"; + public static final String string_0264 = "TestString_0264"; + public static final String string_0265 = "TestString_0265"; + public static final String string_0266 = "TestString_0266"; + public static final String string_0267 = "TestString_0267"; + public static final String string_0268 = "TestString_0268"; + public static final String string_0269 = "TestString_0269"; + public static final String string_0270 = "TestString_0270"; + public static final String string_0271 = "TestString_0271"; + public static final String string_0272 = "TestString_0272"; + public static final String string_0273 = "TestString_0273"; + public static final String string_0274 = "TestString_0274"; + public static final String string_0275 = "TestString_0275"; + public static final String string_0276 = "TestString_0276"; + public static final String string_0277 = "TestString_0277"; + public static final String string_0278 = "TestString_0278"; + public static final String string_0279 = "TestString_0279"; + public static final String string_0280 = "TestString_0280"; + public static final String string_0281 = "TestString_0281"; + public static final String string_0282 = "TestString_0282"; + public static final String string_0283 = "TestString_0283"; + public static final String string_0284 = "TestString_0284"; + public static final String string_0285 = "TestString_0285"; + public static final String string_0286 = "TestString_0286"; + public static final String string_0287 = "TestString_0287"; + public static final String string_0288 = "TestString_0288"; + public static final String string_0289 = "TestString_0289"; + public static final String string_0290 = "TestString_0290"; + public static final String string_0291 = "TestString_0291"; + public static final String string_0292 = "TestString_0292"; + public static final String string_0293 = "TestString_0293"; + public static final String string_0294 = "TestString_0294"; + public static final String string_0295 = "TestString_0295"; + public static final String string_0296 = "TestString_0296"; + public static final String string_0297 = "TestString_0297"; + public static final String string_0298 = "TestString_0298"; + public static final String string_0299 = "TestString_0299"; + public static final String string_0300 = "TestString_0300"; + public static final String string_0301 = "TestString_0301"; + public static final String string_0302 = "TestString_0302"; + public static final String string_0303 = "TestString_0303"; + public static final String string_0304 = "TestString_0304"; + public static final String string_0305 = "TestString_0305"; + public static final String string_0306 = "TestString_0306"; + public static final String string_0307 = "TestString_0307"; + public static final String string_0308 = "TestString_0308"; + public static final String string_0309 = "TestString_0309"; + public static final String string_0310 = "TestString_0310"; + public static final String string_0311 = "TestString_0311"; + public static final String string_0312 = "TestString_0312"; + public static final String string_0313 = "TestString_0313"; + public static final String string_0314 = "TestString_0314"; + public static final String string_0315 = "TestString_0315"; + public static final String string_0316 = "TestString_0316"; + public static final String string_0317 = "TestString_0317"; + public static final String string_0318 = "TestString_0318"; + public static final String string_0319 = "TestString_0319"; + public static final String string_0320 = "TestString_0320"; + public static final String string_0321 = "TestString_0321"; + public static final String string_0322 = "TestString_0322"; + public static final String string_0323 = "TestString_0323"; + public static final String string_0324 = "TestString_0324"; + public static final String string_0325 = "TestString_0325"; + public static final String string_0326 = "TestString_0326"; + public static final String string_0327 = "TestString_0327"; + public static final String string_0328 = "TestString_0328"; + public static final String string_0329 = "TestString_0329"; + public static final String string_0330 = "TestString_0330"; + public static final String string_0331 = "TestString_0331"; + public static final String string_0332 = "TestString_0332"; + public static final String string_0333 = "TestString_0333"; + public static final String string_0334 = "TestString_0334"; + public static final String string_0335 = "TestString_0335"; + public static final String string_0336 = "TestString_0336"; + public static final String string_0337 = "TestString_0337"; + public static final String string_0338 = "TestString_0338"; + public static final String string_0339 = "TestString_0339"; + public static final String string_0340 = "TestString_0340"; + public static final String string_0341 = "TestString_0341"; + public static final String string_0342 = "TestString_0342"; + public static final String string_0343 = "TestString_0343"; + public static final String string_0344 = "TestString_0344"; + public static final String string_0345 = "TestString_0345"; + public static final String string_0346 = "TestString_0346"; + public static final String string_0347 = "TestString_0347"; + public static final String string_0348 = "TestString_0348"; + public static final String string_0349 = "TestString_0349"; + public static final String string_0350 = "TestString_0350"; + public static final String string_0351 = "TestString_0351"; + public static final String string_0352 = "TestString_0352"; + public static final String string_0353 = "TestString_0353"; + public static final String string_0354 = "TestString_0354"; + public static final String string_0355 = "TestString_0355"; + public static final String string_0356 = "TestString_0356"; + public static final String string_0357 = "TestString_0357"; + public static final String string_0358 = "TestString_0358"; + public static final String string_0359 = "TestString_0359"; + public static final String string_0360 = "TestString_0360"; + public static final String string_0361 = "TestString_0361"; + public static final String string_0362 = "TestString_0362"; + public static final String string_0363 = "TestString_0363"; + public static final String string_0364 = "TestString_0364"; + public static final String string_0365 = "TestString_0365"; + public static final String string_0366 = "TestString_0366"; + public static final String string_0367 = "TestString_0367"; + public static final String string_0368 = "TestString_0368"; + public static final String string_0369 = "TestString_0369"; + public static final String string_0370 = "TestString_0370"; + public static final String string_0371 = "TestString_0371"; + public static final String string_0372 = "TestString_0372"; + public static final String string_0373 = "TestString_0373"; + public static final String string_0374 = "TestString_0374"; + public static final String string_0375 = "TestString_0375"; + public static final String string_0376 = "TestString_0376"; + public static final String string_0377 = "TestString_0377"; + public static final String string_0378 = "TestString_0378"; + public static final String string_0379 = "TestString_0379"; + public static final String string_0380 = "TestString_0380"; + public static final String string_0381 = "TestString_0381"; + public static final String string_0382 = "TestString_0382"; + public static final String string_0383 = "TestString_0383"; + public static final String string_0384 = "TestString_0384"; + public static final String string_0385 = "TestString_0385"; + public static final String string_0386 = "TestString_0386"; + public static final String string_0387 = "TestString_0387"; + public static final String string_0388 = "TestString_0388"; + public static final String string_0389 = "TestString_0389"; + public static final String string_0390 = "TestString_0390"; + public static final String string_0391 = "TestString_0391"; + public static final String string_0392 = "TestString_0392"; + public static final String string_0393 = "TestString_0393"; + public static final String string_0394 = "TestString_0394"; + public static final String string_0395 = "TestString_0395"; + public static final String string_0396 = "TestString_0396"; + public static final String string_0397 = "TestString_0397"; + public static final String string_0398 = "TestString_0398"; + public static final String string_0399 = "TestString_0399"; + public static final String string_0400 = "TestString_0400"; + public static final String string_0401 = "TestString_0401"; + public static final String string_0402 = "TestString_0402"; + public static final String string_0403 = "TestString_0403"; + public static final String string_0404 = "TestString_0404"; + public static final String string_0405 = "TestString_0405"; + public static final String string_0406 = "TestString_0406"; + public static final String string_0407 = "TestString_0407"; + public static final String string_0408 = "TestString_0408"; + public static final String string_0409 = "TestString_0409"; + public static final String string_0410 = "TestString_0410"; + public static final String string_0411 = "TestString_0411"; + public static final String string_0412 = "TestString_0412"; + public static final String string_0413 = "TestString_0413"; + public static final String string_0414 = "TestString_0414"; + public static final String string_0415 = "TestString_0415"; + public static final String string_0416 = "TestString_0416"; + public static final String string_0417 = "TestString_0417"; + public static final String string_0418 = "TestString_0418"; + public static final String string_0419 = "TestString_0419"; + public static final String string_0420 = "TestString_0420"; + public static final String string_0421 = "TestString_0421"; + public static final String string_0422 = "TestString_0422"; + public static final String string_0423 = "TestString_0423"; + public static final String string_0424 = "TestString_0424"; + public static final String string_0425 = "TestString_0425"; + public static final String string_0426 = "TestString_0426"; + public static final String string_0427 = "TestString_0427"; + public static final String string_0428 = "TestString_0428"; + public static final String string_0429 = "TestString_0429"; + public static final String string_0430 = "TestString_0430"; + public static final String string_0431 = "TestString_0431"; + public static final String string_0432 = "TestString_0432"; + public static final String string_0433 = "TestString_0433"; + public static final String string_0434 = "TestString_0434"; + public static final String string_0435 = "TestString_0435"; + public static final String string_0436 = "TestString_0436"; + public static final String string_0437 = "TestString_0437"; + public static final String string_0438 = "TestString_0438"; + public static final String string_0439 = "TestString_0439"; + public static final String string_0440 = "TestString_0440"; + public static final String string_0441 = "TestString_0441"; + public static final String string_0442 = "TestString_0442"; + public static final String string_0443 = "TestString_0443"; + public static final String string_0444 = "TestString_0444"; + public static final String string_0445 = "TestString_0445"; + public static final String string_0446 = "TestString_0446"; + public static final String string_0447 = "TestString_0447"; + public static final String string_0448 = "TestString_0448"; + public static final String string_0449 = "TestString_0449"; + public static final String string_0450 = "TestString_0450"; + public static final String string_0451 = "TestString_0451"; + public static final String string_0452 = "TestString_0452"; + public static final String string_0453 = "TestString_0453"; + public static final String string_0454 = "TestString_0454"; + public static final String string_0455 = "TestString_0455"; + public static final String string_0456 = "TestString_0456"; + public static final String string_0457 = "TestString_0457"; + public static final String string_0458 = "TestString_0458"; + public static final String string_0459 = "TestString_0459"; + public static final String string_0460 = "TestString_0460"; + public static final String string_0461 = "TestString_0461"; + public static final String string_0462 = "TestString_0462"; + public static final String string_0463 = "TestString_0463"; + public static final String string_0464 = "TestString_0464"; + public static final String string_0465 = "TestString_0465"; + public static final String string_0466 = "TestString_0466"; + public static final String string_0467 = "TestString_0467"; + public static final String string_0468 = "TestString_0468"; + public static final String string_0469 = "TestString_0469"; + public static final String string_0470 = "TestString_0470"; + public static final String string_0471 = "TestString_0471"; + public static final String string_0472 = "TestString_0472"; + public static final String string_0473 = "TestString_0473"; + public static final String string_0474 = "TestString_0474"; + public static final String string_0475 = "TestString_0475"; + public static final String string_0476 = "TestString_0476"; + public static final String string_0477 = "TestString_0477"; + public static final String string_0478 = "TestString_0478"; + public static final String string_0479 = "TestString_0479"; + public static final String string_0480 = "TestString_0480"; + public static final String string_0481 = "TestString_0481"; + public static final String string_0482 = "TestString_0482"; + public static final String string_0483 = "TestString_0483"; + public static final String string_0484 = "TestString_0484"; + public static final String string_0485 = "TestString_0485"; + public static final String string_0486 = "TestString_0486"; + public static final String string_0487 = "TestString_0487"; + public static final String string_0488 = "TestString_0488"; + public static final String string_0489 = "TestString_0489"; + public static final String string_0490 = "TestString_0490"; + public static final String string_0491 = "TestString_0491"; + public static final String string_0492 = "TestString_0492"; + public static final String string_0493 = "TestString_0493"; + public static final String string_0494 = "TestString_0494"; + public static final String string_0495 = "TestString_0495"; + public static final String string_0496 = "TestString_0496"; + public static final String string_0497 = "TestString_0497"; + public static final String string_0498 = "TestString_0498"; + public static final String string_0499 = "TestString_0499"; + public static final String string_0500 = "TestString_0500"; + public static final String string_0501 = "TestString_0501"; + public static final String string_0502 = "TestString_0502"; + public static final String string_0503 = "TestString_0503"; + public static final String string_0504 = "TestString_0504"; + public static final String string_0505 = "TestString_0505"; + public static final String string_0506 = "TestString_0506"; + public static final String string_0507 = "TestString_0507"; + public static final String string_0508 = "TestString_0508"; + public static final String string_0509 = "TestString_0509"; + public static final String string_0510 = "TestString_0510"; + public static final String string_0511 = "TestString_0511"; + public static final String string_0512 = "TestString_0512"; + public static final String string_0513 = "TestString_0513"; + public static final String string_0514 = "TestString_0514"; + public static final String string_0515 = "TestString_0515"; + public static final String string_0516 = "TestString_0516"; + public static final String string_0517 = "TestString_0517"; + public static final String string_0518 = "TestString_0518"; + public static final String string_0519 = "TestString_0519"; + public static final String string_0520 = "TestString_0520"; + public static final String string_0521 = "TestString_0521"; + public static final String string_0522 = "TestString_0522"; + public static final String string_0523 = "TestString_0523"; + public static final String string_0524 = "TestString_0524"; + public static final String string_0525 = "TestString_0525"; + public static final String string_0526 = "TestString_0526"; + public static final String string_0527 = "TestString_0527"; + public static final String string_0528 = "TestString_0528"; + public static final String string_0529 = "TestString_0529"; + public static final String string_0530 = "TestString_0530"; + public static final String string_0531 = "TestString_0531"; + public static final String string_0532 = "TestString_0532"; + public static final String string_0533 = "TestString_0533"; + public static final String string_0534 = "TestString_0534"; + public static final String string_0535 = "TestString_0535"; + public static final String string_0536 = "TestString_0536"; + public static final String string_0537 = "TestString_0537"; + public static final String string_0538 = "TestString_0538"; + public static final String string_0539 = "TestString_0539"; + public static final String string_0540 = "TestString_0540"; + public static final String string_0541 = "TestString_0541"; + public static final String string_0542 = "TestString_0542"; + public static final String string_0543 = "TestString_0543"; + public static final String string_0544 = "TestString_0544"; + public static final String string_0545 = "TestString_0545"; + public static final String string_0546 = "TestString_0546"; + public static final String string_0547 = "TestString_0547"; + public static final String string_0548 = "TestString_0548"; + public static final String string_0549 = "TestString_0549"; + public static final String string_0550 = "TestString_0550"; + public static final String string_0551 = "TestString_0551"; + public static final String string_0552 = "TestString_0552"; + public static final String string_0553 = "TestString_0553"; + public static final String string_0554 = "TestString_0554"; + public static final String string_0555 = "TestString_0555"; + public static final String string_0556 = "TestString_0556"; + public static final String string_0557 = "TestString_0557"; + public static final String string_0558 = "TestString_0558"; + public static final String string_0559 = "TestString_0559"; + public static final String string_0560 = "TestString_0560"; + public static final String string_0561 = "TestString_0561"; + public static final String string_0562 = "TestString_0562"; + public static final String string_0563 = "TestString_0563"; + public static final String string_0564 = "TestString_0564"; + public static final String string_0565 = "TestString_0565"; + public static final String string_0566 = "TestString_0566"; + public static final String string_0567 = "TestString_0567"; + public static final String string_0568 = "TestString_0568"; + public static final String string_0569 = "TestString_0569"; + public static final String string_0570 = "TestString_0570"; + public static final String string_0571 = "TestString_0571"; + public static final String string_0572 = "TestString_0572"; + public static final String string_0573 = "TestString_0573"; + public static final String string_0574 = "TestString_0574"; + public static final String string_0575 = "TestString_0575"; + public static final String string_0576 = "TestString_0576"; + public static final String string_0577 = "TestString_0577"; + public static final String string_0578 = "TestString_0578"; + public static final String string_0579 = "TestString_0579"; + public static final String string_0580 = "TestString_0580"; + public static final String string_0581 = "TestString_0581"; + public static final String string_0582 = "TestString_0582"; + public static final String string_0583 = "TestString_0583"; + public static final String string_0584 = "TestString_0584"; + public static final String string_0585 = "TestString_0585"; + public static final String string_0586 = "TestString_0586"; + public static final String string_0587 = "TestString_0587"; + public static final String string_0588 = "TestString_0588"; + public static final String string_0589 = "TestString_0589"; + public static final String string_0590 = "TestString_0590"; + public static final String string_0591 = "TestString_0591"; + public static final String string_0592 = "TestString_0592"; + public static final String string_0593 = "TestString_0593"; + public static final String string_0594 = "TestString_0594"; + public static final String string_0595 = "TestString_0595"; + public static final String string_0596 = "TestString_0596"; + public static final String string_0597 = "TestString_0597"; + public static final String string_0598 = "TestString_0598"; + public static final String string_0599 = "TestString_0599"; + public static final String string_0600 = "TestString_0600"; + public static final String string_0601 = "TestString_0601"; + public static final String string_0602 = "TestString_0602"; + public static final String string_0603 = "TestString_0603"; + public static final String string_0604 = "TestString_0604"; + public static final String string_0605 = "TestString_0605"; + public static final String string_0606 = "TestString_0606"; + public static final String string_0607 = "TestString_0607"; + public static final String string_0608 = "TestString_0608"; + public static final String string_0609 = "TestString_0609"; + public static final String string_0610 = "TestString_0610"; + public static final String string_0611 = "TestString_0611"; + public static final String string_0612 = "TestString_0612"; + public static final String string_0613 = "TestString_0613"; + public static final String string_0614 = "TestString_0614"; + public static final String string_0615 = "TestString_0615"; + public static final String string_0616 = "TestString_0616"; + public static final String string_0617 = "TestString_0617"; + public static final String string_0618 = "TestString_0618"; + public static final String string_0619 = "TestString_0619"; + public static final String string_0620 = "TestString_0620"; + public static final String string_0621 = "TestString_0621"; + public static final String string_0622 = "TestString_0622"; + public static final String string_0623 = "TestString_0623"; + public static final String string_0624 = "TestString_0624"; + public static final String string_0625 = "TestString_0625"; + public static final String string_0626 = "TestString_0626"; + public static final String string_0627 = "TestString_0627"; + public static final String string_0628 = "TestString_0628"; + public static final String string_0629 = "TestString_0629"; + public static final String string_0630 = "TestString_0630"; + public static final String string_0631 = "TestString_0631"; + public static final String string_0632 = "TestString_0632"; + public static final String string_0633 = "TestString_0633"; + public static final String string_0634 = "TestString_0634"; + public static final String string_0635 = "TestString_0635"; + public static final String string_0636 = "TestString_0636"; + public static final String string_0637 = "TestString_0637"; + public static final String string_0638 = "TestString_0638"; + public static final String string_0639 = "TestString_0639"; + public static final String string_0640 = "TestString_0640"; + public static final String string_0641 = "TestString_0641"; + public static final String string_0642 = "TestString_0642"; + public static final String string_0643 = "TestString_0643"; + public static final String string_0644 = "TestString_0644"; + public static final String string_0645 = "TestString_0645"; + public static final String string_0646 = "TestString_0646"; + public static final String string_0647 = "TestString_0647"; + public static final String string_0648 = "TestString_0648"; + public static final String string_0649 = "TestString_0649"; + public static final String string_0650 = "TestString_0650"; + public static final String string_0651 = "TestString_0651"; + public static final String string_0652 = "TestString_0652"; + public static final String string_0653 = "TestString_0653"; + public static final String string_0654 = "TestString_0654"; + public static final String string_0655 = "TestString_0655"; + public static final String string_0656 = "TestString_0656"; + public static final String string_0657 = "TestString_0657"; + public static final String string_0658 = "TestString_0658"; + public static final String string_0659 = "TestString_0659"; + public static final String string_0660 = "TestString_0660"; + public static final String string_0661 = "TestString_0661"; + public static final String string_0662 = "TestString_0662"; + public static final String string_0663 = "TestString_0663"; + public static final String string_0664 = "TestString_0664"; + public static final String string_0665 = "TestString_0665"; + public static final String string_0666 = "TestString_0666"; + public static final String string_0667 = "TestString_0667"; + public static final String string_0668 = "TestString_0668"; + public static final String string_0669 = "TestString_0669"; + public static final String string_0670 = "TestString_0670"; + public static final String string_0671 = "TestString_0671"; + public static final String string_0672 = "TestString_0672"; + public static final String string_0673 = "TestString_0673"; + public static final String string_0674 = "TestString_0674"; + public static final String string_0675 = "TestString_0675"; + public static final String string_0676 = "TestString_0676"; + public static final String string_0677 = "TestString_0677"; + public static final String string_0678 = "TestString_0678"; + public static final String string_0679 = "TestString_0679"; + public static final String string_0680 = "TestString_0680"; + public static final String string_0681 = "TestString_0681"; + public static final String string_0682 = "TestString_0682"; + public static final String string_0683 = "TestString_0683"; + public static final String string_0684 = "TestString_0684"; + public static final String string_0685 = "TestString_0685"; + public static final String string_0686 = "TestString_0686"; + public static final String string_0687 = "TestString_0687"; + public static final String string_0688 = "TestString_0688"; + public static final String string_0689 = "TestString_0689"; + public static final String string_0690 = "TestString_0690"; + public static final String string_0691 = "TestString_0691"; + public static final String string_0692 = "TestString_0692"; + public static final String string_0693 = "TestString_0693"; + public static final String string_0694 = "TestString_0694"; + public static final String string_0695 = "TestString_0695"; + public static final String string_0696 = "TestString_0696"; + public static final String string_0697 = "TestString_0697"; + public static final String string_0698 = "TestString_0698"; + public static final String string_0699 = "TestString_0699"; + public static final String string_0700 = "TestString_0700"; + public static final String string_0701 = "TestString_0701"; + public static final String string_0702 = "TestString_0702"; + public static final String string_0703 = "TestString_0703"; + public static final String string_0704 = "TestString_0704"; + public static final String string_0705 = "TestString_0705"; + public static final String string_0706 = "TestString_0706"; + public static final String string_0707 = "TestString_0707"; + public static final String string_0708 = "TestString_0708"; + public static final String string_0709 = "TestString_0709"; + public static final String string_0710 = "TestString_0710"; + public static final String string_0711 = "TestString_0711"; + public static final String string_0712 = "TestString_0712"; + public static final String string_0713 = "TestString_0713"; + public static final String string_0714 = "TestString_0714"; + public static final String string_0715 = "TestString_0715"; + public static final String string_0716 = "TestString_0716"; + public static final String string_0717 = "TestString_0717"; + public static final String string_0718 = "TestString_0718"; + public static final String string_0719 = "TestString_0719"; + public static final String string_0720 = "TestString_0720"; + public static final String string_0721 = "TestString_0721"; + public static final String string_0722 = "TestString_0722"; + public static final String string_0723 = "TestString_0723"; + public static final String string_0724 = "TestString_0724"; + public static final String string_0725 = "TestString_0725"; + public static final String string_0726 = "TestString_0726"; + public static final String string_0727 = "TestString_0727"; + public static final String string_0728 = "TestString_0728"; + public static final String string_0729 = "TestString_0729"; + public static final String string_0730 = "TestString_0730"; + public static final String string_0731 = "TestString_0731"; + public static final String string_0732 = "TestString_0732"; + public static final String string_0733 = "TestString_0733"; + public static final String string_0734 = "TestString_0734"; + public static final String string_0735 = "TestString_0735"; + public static final String string_0736 = "TestString_0736"; + public static final String string_0737 = "TestString_0737"; + public static final String string_0738 = "TestString_0738"; + public static final String string_0739 = "TestString_0739"; + public static final String string_0740 = "TestString_0740"; + public static final String string_0741 = "TestString_0741"; + public static final String string_0742 = "TestString_0742"; + public static final String string_0743 = "TestString_0743"; + public static final String string_0744 = "TestString_0744"; + public static final String string_0745 = "TestString_0745"; + public static final String string_0746 = "TestString_0746"; + public static final String string_0747 = "TestString_0747"; + public static final String string_0748 = "TestString_0748"; + public static final String string_0749 = "TestString_0749"; + public static final String string_0750 = "TestString_0750"; + public static final String string_0751 = "TestString_0751"; + public static final String string_0752 = "TestString_0752"; + public static final String string_0753 = "TestString_0753"; + public static final String string_0754 = "TestString_0754"; + public static final String string_0755 = "TestString_0755"; + public static final String string_0756 = "TestString_0756"; + public static final String string_0757 = "TestString_0757"; + public static final String string_0758 = "TestString_0758"; + public static final String string_0759 = "TestString_0759"; + public static final String string_0760 = "TestString_0760"; + public static final String string_0761 = "TestString_0761"; + public static final String string_0762 = "TestString_0762"; + public static final String string_0763 = "TestString_0763"; + public static final String string_0764 = "TestString_0764"; + public static final String string_0765 = "TestString_0765"; + public static final String string_0766 = "TestString_0766"; + public static final String string_0767 = "TestString_0767"; + public static final String string_0768 = "TestString_0768"; + public static final String string_0769 = "TestString_0769"; + public static final String string_0770 = "TestString_0770"; + public static final String string_0771 = "TestString_0771"; + public static final String string_0772 = "TestString_0772"; + public static final String string_0773 = "TestString_0773"; + public static final String string_0774 = "TestString_0774"; + public static final String string_0775 = "TestString_0775"; + public static final String string_0776 = "TestString_0776"; + public static final String string_0777 = "TestString_0777"; + public static final String string_0778 = "TestString_0778"; + public static final String string_0779 = "TestString_0779"; + public static final String string_0780 = "TestString_0780"; + public static final String string_0781 = "TestString_0781"; + public static final String string_0782 = "TestString_0782"; + public static final String string_0783 = "TestString_0783"; + public static final String string_0784 = "TestString_0784"; + public static final String string_0785 = "TestString_0785"; + public static final String string_0786 = "TestString_0786"; + public static final String string_0787 = "TestString_0787"; + public static final String string_0788 = "TestString_0788"; + public static final String string_0789 = "TestString_0789"; + public static final String string_0790 = "TestString_0790"; + public static final String string_0791 = "TestString_0791"; + public static final String string_0792 = "TestString_0792"; + public static final String string_0793 = "TestString_0793"; + public static final String string_0794 = "TestString_0794"; + public static final String string_0795 = "TestString_0795"; + public static final String string_0796 = "TestString_0796"; + public static final String string_0797 = "TestString_0797"; + public static final String string_0798 = "TestString_0798"; + public static final String string_0799 = "TestString_0799"; + public static final String string_0800 = "TestString_0800"; + public static final String string_0801 = "TestString_0801"; + public static final String string_0802 = "TestString_0802"; + public static final String string_0803 = "TestString_0803"; + public static final String string_0804 = "TestString_0804"; + public static final String string_0805 = "TestString_0805"; + public static final String string_0806 = "TestString_0806"; + public static final String string_0807 = "TestString_0807"; + public static final String string_0808 = "TestString_0808"; + public static final String string_0809 = "TestString_0809"; + public static final String string_0810 = "TestString_0810"; + public static final String string_0811 = "TestString_0811"; + public static final String string_0812 = "TestString_0812"; + public static final String string_0813 = "TestString_0813"; + public static final String string_0814 = "TestString_0814"; + public static final String string_0815 = "TestString_0815"; + public static final String string_0816 = "TestString_0816"; + public static final String string_0817 = "TestString_0817"; + public static final String string_0818 = "TestString_0818"; + public static final String string_0819 = "TestString_0819"; + public static final String string_0820 = "TestString_0820"; + public static final String string_0821 = "TestString_0821"; + public static final String string_0822 = "TestString_0822"; + public static final String string_0823 = "TestString_0823"; + public static final String string_0824 = "TestString_0824"; + public static final String string_0825 = "TestString_0825"; + public static final String string_0826 = "TestString_0826"; + public static final String string_0827 = "TestString_0827"; + public static final String string_0828 = "TestString_0828"; + public static final String string_0829 = "TestString_0829"; + public static final String string_0830 = "TestString_0830"; + public static final String string_0831 = "TestString_0831"; + public static final String string_0832 = "TestString_0832"; + public static final String string_0833 = "TestString_0833"; + public static final String string_0834 = "TestString_0834"; + public static final String string_0835 = "TestString_0835"; + public static final String string_0836 = "TestString_0836"; + public static final String string_0837 = "TestString_0837"; + public static final String string_0838 = "TestString_0838"; + public static final String string_0839 = "TestString_0839"; + public static final String string_0840 = "TestString_0840"; + public static final String string_0841 = "TestString_0841"; + public static final String string_0842 = "TestString_0842"; + public static final String string_0843 = "TestString_0843"; + public static final String string_0844 = "TestString_0844"; + public static final String string_0845 = "TestString_0845"; + public static final String string_0846 = "TestString_0846"; + public static final String string_0847 = "TestString_0847"; + public static final String string_0848 = "TestString_0848"; + public static final String string_0849 = "TestString_0849"; + public static final String string_0850 = "TestString_0850"; + public static final String string_0851 = "TestString_0851"; + public static final String string_0852 = "TestString_0852"; + public static final String string_0853 = "TestString_0853"; + public static final String string_0854 = "TestString_0854"; + public static final String string_0855 = "TestString_0855"; + public static final String string_0856 = "TestString_0856"; + public static final String string_0857 = "TestString_0857"; + public static final String string_0858 = "TestString_0858"; + public static final String string_0859 = "TestString_0859"; + public static final String string_0860 = "TestString_0860"; + public static final String string_0861 = "TestString_0861"; + public static final String string_0862 = "TestString_0862"; + public static final String string_0863 = "TestString_0863"; + public static final String string_0864 = "TestString_0864"; + public static final String string_0865 = "TestString_0865"; + public static final String string_0866 = "TestString_0866"; + public static final String string_0867 = "TestString_0867"; + public static final String string_0868 = "TestString_0868"; + public static final String string_0869 = "TestString_0869"; + public static final String string_0870 = "TestString_0870"; + public static final String string_0871 = "TestString_0871"; + public static final String string_0872 = "TestString_0872"; + public static final String string_0873 = "TestString_0873"; + public static final String string_0874 = "TestString_0874"; + public static final String string_0875 = "TestString_0875"; + public static final String string_0876 = "TestString_0876"; + public static final String string_0877 = "TestString_0877"; + public static final String string_0878 = "TestString_0878"; + public static final String string_0879 = "TestString_0879"; + public static final String string_0880 = "TestString_0880"; + public static final String string_0881 = "TestString_0881"; + public static final String string_0882 = "TestString_0882"; + public static final String string_0883 = "TestString_0883"; + public static final String string_0884 = "TestString_0884"; + public static final String string_0885 = "TestString_0885"; + public static final String string_0886 = "TestString_0886"; + public static final String string_0887 = "TestString_0887"; + public static final String string_0888 = "TestString_0888"; + public static final String string_0889 = "TestString_0889"; + public static final String string_0890 = "TestString_0890"; + public static final String string_0891 = "TestString_0891"; + public static final String string_0892 = "TestString_0892"; + public static final String string_0893 = "TestString_0893"; + public static final String string_0894 = "TestString_0894"; + public static final String string_0895 = "TestString_0895"; + public static final String string_0896 = "TestString_0896"; + public static final String string_0897 = "TestString_0897"; + public static final String string_0898 = "TestString_0898"; + public static final String string_0899 = "TestString_0899"; + public static final String string_0900 = "TestString_0900"; + public static final String string_0901 = "TestString_0901"; + public static final String string_0902 = "TestString_0902"; + public static final String string_0903 = "TestString_0903"; + public static final String string_0904 = "TestString_0904"; + public static final String string_0905 = "TestString_0905"; + public static final String string_0906 = "TestString_0906"; + public static final String string_0907 = "TestString_0907"; + public static final String string_0908 = "TestString_0908"; + public static final String string_0909 = "TestString_0909"; + public static final String string_0910 = "TestString_0910"; + public static final String string_0911 = "TestString_0911"; + public static final String string_0912 = "TestString_0912"; + public static final String string_0913 = "TestString_0913"; + public static final String string_0914 = "TestString_0914"; + public static final String string_0915 = "TestString_0915"; + public static final String string_0916 = "TestString_0916"; + public static final String string_0917 = "TestString_0917"; + public static final String string_0918 = "TestString_0918"; + public static final String string_0919 = "TestString_0919"; + public static final String string_0920 = "TestString_0920"; + public static final String string_0921 = "TestString_0921"; + public static final String string_0922 = "TestString_0922"; + public static final String string_0923 = "TestString_0923"; + public static final String string_0924 = "TestString_0924"; + public static final String string_0925 = "TestString_0925"; + public static final String string_0926 = "TestString_0926"; + public static final String string_0927 = "TestString_0927"; + public static final String string_0928 = "TestString_0928"; + public static final String string_0929 = "TestString_0929"; + public static final String string_0930 = "TestString_0930"; + public static final String string_0931 = "TestString_0931"; + public static final String string_0932 = "TestString_0932"; + public static final String string_0933 = "TestString_0933"; + public static final String string_0934 = "TestString_0934"; + public static final String string_0935 = "TestString_0935"; + public static final String string_0936 = "TestString_0936"; + public static final String string_0937 = "TestString_0937"; + public static final String string_0938 = "TestString_0938"; + public static final String string_0939 = "TestString_0939"; + public static final String string_0940 = "TestString_0940"; + public static final String string_0941 = "TestString_0941"; + public static final String string_0942 = "TestString_0942"; + public static final String string_0943 = "TestString_0943"; + public static final String string_0944 = "TestString_0944"; + public static final String string_0945 = "TestString_0945"; + public static final String string_0946 = "TestString_0946"; + public static final String string_0947 = "TestString_0947"; + public static final String string_0948 = "TestString_0948"; + public static final String string_0949 = "TestString_0949"; + public static final String string_0950 = "TestString_0950"; + public static final String string_0951 = "TestString_0951"; + public static final String string_0952 = "TestString_0952"; + public static final String string_0953 = "TestString_0953"; + public static final String string_0954 = "TestString_0954"; + public static final String string_0955 = "TestString_0955"; + public static final String string_0956 = "TestString_0956"; + public static final String string_0957 = "TestString_0957"; + public static final String string_0958 = "TestString_0958"; + public static final String string_0959 = "TestString_0959"; + public static final String string_0960 = "TestString_0960"; + public static final String string_0961 = "TestString_0961"; + public static final String string_0962 = "TestString_0962"; + public static final String string_0963 = "TestString_0963"; + public static final String string_0964 = "TestString_0964"; + public static final String string_0965 = "TestString_0965"; + public static final String string_0966 = "TestString_0966"; + public static final String string_0967 = "TestString_0967"; + public static final String string_0968 = "TestString_0968"; + public static final String string_0969 = "TestString_0969"; + public static final String string_0970 = "TestString_0970"; + public static final String string_0971 = "TestString_0971"; + public static final String string_0972 = "TestString_0972"; + public static final String string_0973 = "TestString_0973"; + public static final String string_0974 = "TestString_0974"; + public static final String string_0975 = "TestString_0975"; + public static final String string_0976 = "TestString_0976"; + public static final String string_0977 = "TestString_0977"; + public static final String string_0978 = "TestString_0978"; + public static final String string_0979 = "TestString_0979"; + public static final String string_0980 = "TestString_0980"; + public static final String string_0981 = "TestString_0981"; + public static final String string_0982 = "TestString_0982"; + public static final String string_0983 = "TestString_0983"; + public static final String string_0984 = "TestString_0984"; + public static final String string_0985 = "TestString_0985"; + public static final String string_0986 = "TestString_0986"; + public static final String string_0987 = "TestString_0987"; + public static final String string_0988 = "TestString_0988"; + public static final String string_0989 = "TestString_0989"; + public static final String string_0990 = "TestString_0990"; + public static final String string_0991 = "TestString_0991"; + public static final String string_0992 = "TestString_0992"; + public static final String string_0993 = "TestString_0993"; + public static final String string_0994 = "TestString_0994"; + public static final String string_0995 = "TestString_0995"; + public static final String string_0996 = "TestString_0996"; + public static final String string_0997 = "TestString_0997"; + public static final String string_0998 = "TestString_0998"; + public static final String string_0999 = "TestString_0999"; + public static final String string_1000 = "TestString_1000"; + public static final String string_1001 = "TestString_1001"; + public static final String string_1002 = "TestString_1002"; + public static final String string_1003 = "TestString_1003"; + public static final String string_1004 = "TestString_1004"; + public static final String string_1005 = "TestString_1005"; + public static final String string_1006 = "TestString_1006"; + public static final String string_1007 = "TestString_1007"; + public static final String string_1008 = "TestString_1008"; + public static final String string_1009 = "TestString_1009"; + public static final String string_1010 = "TestString_1010"; + public static final String string_1011 = "TestString_1011"; + public static final String string_1012 = "TestString_1012"; + public static final String string_1013 = "TestString_1013"; + public static final String string_1014 = "TestString_1014"; + public static final String string_1015 = "TestString_1015"; + public static final String string_1016 = "TestString_1016"; + public static final String string_1017 = "TestString_1017"; + public static final String string_1018 = "TestString_1018"; + public static final String string_1019 = "TestString_1019"; + public static final String string_1020 = "TestString_1020"; + public static final String string_1021 = "TestString_1021"; + public static final String string_1022 = "TestString_1022"; + public static final String string_1023 = "TestString_1023"; + public static final String string_1024 = "TestString_1024"; + + public void timeConstStringsWithConflict(int count) { + for (int i = 0; i < count; ++i) { + $noinline$foo("TestString_0000"); + $noinline$foo("TestString_1024"); + } + } + + public void timeConstStringsWithoutConflict(int count) { + for (int i = 0; i < count; ++i) { + $noinline$foo("TestString_0001"); + $noinline$foo("TestString_1023"); + } + } + + static void $noinline$foo(String s) { + if (doThrow) { throw new Error(); } + } + + public static boolean doThrow = false; +} diff --git a/benchmark/jni-perf/perf_jni.cc b/benchmark/jni-perf/perf_jni.cc index cd8d520f16..06dded8dfb 100644 --- a/benchmark/jni-perf/perf_jni.cc +++ b/benchmark/jni-perf/perf_jni.cc @@ -17,7 +17,7 @@ #include <assert.h> #include "jni.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { diff --git a/benchmark/jobject-benchmark/jobject_benchmark.cc b/benchmark/jobject-benchmark/jobject_benchmark.cc index e7ca9ebc1e..4b2c024625 100644 --- a/benchmark/jobject-benchmark/jobject_benchmark.cc +++ b/benchmark/jobject-benchmark/jobject_benchmark.cc @@ -16,8 +16,9 @@ #include "jni.h" +#include "java_vm_ext.h" #include "mirror/class-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace { @@ -25,10 +26,10 @@ namespace { extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeAddRemoveLocal( JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); CHECK(obj != nullptr); for (jint i = 0; i < reps; ++i) { - jobject ref = soa.Env()->AddLocalReference<jobject>(obj); + jobject ref = soa.Env()->AddLocalReference<jobject>(obj.Decode()); soa.Env()->DeleteLocalRef(ref); } } @@ -36,11 +37,11 @@ extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeAddRemoveLocal( extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeDecodeLocal( JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); CHECK(obj != nullptr); - jobject ref = soa.Env()->AddLocalReference<jobject>(obj); + jobject ref = soa.Env()->AddLocalReference<jobject>(obj.Decode()); for (jint i = 0; i < reps; ++i) { - CHECK_EQ(soa.Decode<mirror::Object*>(ref), obj); + CHECK_EQ(soa.Decode<mirror::Object>(ref), obj); } soa.Env()->DeleteLocalRef(ref); } @@ -48,7 +49,7 @@ extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeDecodeLocal( extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeAddRemoveGlobal( JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); CHECK(obj != nullptr); for (jint i = 0; i < reps; ++i) { jobject ref = soa.Vm()->AddGlobalRef(soa.Self(), obj); @@ -59,11 +60,11 @@ extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeAddRemoveGlobal( extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeDecodeGlobal( JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); CHECK(obj != nullptr); jobject ref = soa.Vm()->AddGlobalRef(soa.Self(), obj); for (jint i = 0; i < reps; ++i) { - CHECK_EQ(soa.Decode<mirror::Object*>(ref), obj); + CHECK_EQ(soa.Decode<mirror::Object>(ref), obj); } soa.Vm()->DeleteGlobalRef(soa.Self(), ref); } @@ -71,7 +72,7 @@ extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeDecodeGlobal( extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeAddRemoveWeakGlobal( JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); CHECK(obj != nullptr); for (jint i = 0; i < reps; ++i) { jobject ref = soa.Vm()->AddWeakGlobalRef(soa.Self(), obj); @@ -82,11 +83,11 @@ extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeAddRemoveWeakGlobal( extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeDecodeWeakGlobal( JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); CHECK(obj != nullptr); jobject ref = soa.Vm()->AddWeakGlobalRef(soa.Self(), obj); for (jint i = 0; i < reps; ++i) { - CHECK_EQ(soa.Decode<mirror::Object*>(ref), obj); + CHECK_EQ(soa.Decode<mirror::Object>(ref), obj); } soa.Vm()->DeleteWeakGlobalRef(soa.Self(), ref); } @@ -95,7 +96,7 @@ extern "C" JNIEXPORT void JNICALL Java_JObjectBenchmark_timeDecodeHandleScopeRef JNIEnv* env, jobject jobj, jint reps) { ScopedObjectAccess soa(env); for (jint i = 0; i < reps; ++i) { - soa.Decode<mirror::Object*>(jobj); + soa.Decode<mirror::Object>(jobj); } } diff --git a/compiler/Android.bp b/compiler/Android.bp index f264d3023b..7fb009adc0 100644 --- a/compiler/Android.bp +++ b/compiler/Android.bp @@ -31,8 +31,6 @@ art_cc_defaults { "dex/verified_method.cc", "dex/verification_results.cc", "dex/quick_compiler_callbacks.cc", - "dex/quick/dex_file_method_inliner.cc", - "dex/quick/dex_file_to_method_inliner_map.cc", "driver/compiled_method_storage.cc", "driver/compiler_driver.cc", "driver/compiler_options.cc", diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index 2af4d72bb2..b726649138 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -23,7 +23,6 @@ #include "class_linker.h" #include "compiled_method.h" #include "dex/quick_compiler_callbacks.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -33,7 +32,7 @@ #include "mirror/dex_cache.h" #include "mirror/object-inl.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" @@ -109,7 +108,8 @@ void CommonCompilerTest::MakeExecutable(const void* code_start, size_t code_leng FlushInstructionCache(reinterpret_cast<char*>(base), reinterpret_cast<char*>(base + len)); } -void CommonCompilerTest::MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name) { +void CommonCompilerTest::MakeExecutable(ObjPtr<mirror::ClassLoader> class_loader, + const char* class_name) { std::string class_descriptor(DotToDescriptor(class_name)); Thread* self = Thread::Current(); StackHandleScope<1> hs(self); @@ -176,7 +176,6 @@ void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind, size_t number_of_threads) { compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - method_inliner_map_.get(), kind, isa, instruction_set_features_.get(), @@ -200,9 +199,7 @@ void CommonCompilerTest::SetUpRuntimeOptions(RuntimeOptions* options) { compiler_options_.reset(new CompilerOptions); verification_results_.reset(new VerificationResults(compiler_options_.get())); - method_inliner_map_.reset(new DexFileToMethodInlinerMap); callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(), - method_inliner_map_.get(), CompilerCallbacks::CallbackMode::kCompileApp)); } @@ -223,7 +220,6 @@ void CommonCompilerTest::TearDown() { timer_.reset(); compiler_driver_.reset(); callbacks_.reset(); - method_inliner_map_.reset(); verification_results_.reset(); compiler_options_.reset(); image_reservation_.reset(); diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index 523912119e..f4838c1119 100644 --- a/compiler/common_compiler_test.h +++ b/compiler/common_compiler_test.h @@ -34,7 +34,6 @@ namespace mirror { class CompilerDriver; class CompilerOptions; class CumulativeLogger; -class DexFileToMethodInlinerMap; class VerificationResults; template<class T> class Handle; @@ -51,7 +50,7 @@ class CommonCompilerTest : public CommonRuntimeTest { static void MakeExecutable(const void* code_start, size_t code_length); - void MakeExecutable(mirror::ClassLoader* class_loader, const char* class_name) + void MakeExecutable(ObjPtr<mirror::ClassLoader> class_loader, const char* class_name) REQUIRES_SHARED(Locks::mutator_lock_); protected: @@ -102,7 +101,6 @@ class CommonCompilerTest : public CommonRuntimeTest { Compiler::Kind compiler_kind_ = Compiler::kOptimizing; std::unique_ptr<CompilerOptions> compiler_options_; std::unique_ptr<VerificationResults> verification_results_; - std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_; std::unique_ptr<CompilerDriver> compiler_driver_; std::unique_ptr<CumulativeLogger> timer_; std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; diff --git a/compiler/dex/dex_to_dex_compiler.cc b/compiler/dex/dex_to_dex_compiler.cc index e0abf197d5..236a3b24ed 100644 --- a/compiler/dex/dex_to_dex_compiler.cc +++ b/compiler/dex/dex_to_dex_compiler.cc @@ -280,7 +280,7 @@ void DexCompiler::CompileInvokeVirtual(Instruction* inst, uint32_t dex_pc, ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(unit_.GetClassLoader()))); + soa.Decode<mirror::ClassLoader>(unit_.GetClassLoader()))); ClassLinker* class_linker = unit_.GetClassLinker(); ArtMethod* resolved_method = class_linker->ResolveMethod<ClassLinker::kForceICCECheck>( diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc deleted file mode 100644 index 67505541c2..0000000000 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ /dev/null @@ -1,824 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "dex_file_method_inliner.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/mutex-inl.h" -#include "driver/compiler_driver.h" -#include "thread-inl.h" -#include "dex_instruction-inl.h" -#include "driver/dex_compilation_unit.h" -#include "verifier/method_verifier-inl.h" - -namespace art { - -namespace { // anonymous namespace - -static constexpr bool kIntrinsicIsStatic[] = { - true, // kIntrinsicDoubleCvt - true, // kIntrinsicFloatCvt - true, // kIntrinsicFloat2Int - true, // kIntrinsicDouble2Long - true, // kIntrinsicFloatIsInfinite - true, // kIntrinsicDoubleIsInfinite - true, // kIntrinsicFloatIsNaN - true, // kIntrinsicDoubleIsNaN - true, // kIntrinsicReverseBits - true, // kIntrinsicReverseBytes - true, // kIntrinsicBitCount - true, // kIntrinsicCompare, - true, // kIntrinsicHighestOneBit - true, // kIntrinsicLowestOneBit - true, // kIntrinsicNumberOfLeadingZeros - true, // kIntrinsicNumberOfTrailingZeros - true, // kIntrinsicRotateRight - true, // kIntrinsicRotateLeft - true, // kIntrinsicSignum - true, // kIntrinsicAbsInt - true, // kIntrinsicAbsLong - true, // kIntrinsicAbsFloat - true, // kIntrinsicAbsDouble - true, // kIntrinsicMinMaxInt - true, // kIntrinsicMinMaxLong - true, // kIntrinsicMinMaxFloat - true, // kIntrinsicMinMaxDouble - true, // kIntrinsicCos - true, // kIntrinsicSin - true, // kIntrinsicAcos - true, // kIntrinsicAsin - true, // kIntrinsicAtan - true, // kIntrinsicAtan2 - true, // kIntrinsicCbrt - true, // kIntrinsicCosh - true, // kIntrinsicExp - true, // kIntrinsicExpm1 - true, // kIntrinsicHypot - true, // kIntrinsicLog - true, // kIntrinsicLog10 - true, // kIntrinsicNextAfter - true, // kIntrinsicSinh - true, // kIntrinsicTan - true, // kIntrinsicTanh - true, // kIntrinsicSqrt - true, // kIntrinsicCeil - true, // kIntrinsicFloor - true, // kIntrinsicRint - true, // kIntrinsicRoundFloat - true, // kIntrinsicRoundDouble - false, // kIntrinsicReferenceGetReferent - false, // kIntrinsicCharAt - false, // kIntrinsicCompareTo - false, // kIntrinsicEquals - false, // kIntrinsicGetCharsNoCheck - false, // kIntrinsicIsEmptyOrLength - false, // kIntrinsicIndexOf - true, // kIntrinsicNewStringFromBytes - true, // kIntrinsicNewStringFromChars - true, // kIntrinsicNewStringFromString - true, // kIntrinsicCurrentThread - true, // kIntrinsicPeek - true, // kIntrinsicPoke - false, // kIntrinsicCas - false, // kIntrinsicUnsafeGet - false, // kIntrinsicUnsafePut - false, // kIntrinsicUnsafeGetAndAddInt, - false, // kIntrinsicUnsafeGetAndAddLong, - false, // kIntrinsicUnsafeGetAndSetInt, - false, // kIntrinsicUnsafeGetAndSetLong, - false, // kIntrinsicUnsafeGetAndSetObject, - false, // kIntrinsicUnsafeLoadFence, - false, // kIntrinsicUnsafeStoreFence, - false, // kIntrinsicUnsafeFullFence, - true, // kIntrinsicSystemArrayCopyCharArray - true, // kIntrinsicSystemArrayCopy -}; -static_assert(arraysize(kIntrinsicIsStatic) == kInlineOpNop, - "arraysize of kIntrinsicIsStatic unexpected"); -static_assert(kIntrinsicIsStatic[kIntrinsicDoubleCvt], "DoubleCvt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloatCvt], "FloatCvt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloat2Int], "Float2Int must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicDouble2Long], "Double2Long must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsInfinite], "FloatIsInfinite must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsInfinite], "DoubleIsInfinite must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsNaN], "FloatIsNaN must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsNaN], "DoubleIsNaN must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicReverseBits], "ReverseBits must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicReverseBytes], "ReverseBytes must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicBitCount], "BitCount must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCompare], "Compare must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicHighestOneBit], "HighestOneBit must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicLowestOneBit], "LowestOneBit must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfLeadingZeros], - "NumberOfLeadingZeros must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfTrailingZeros], - "NumberOfTrailingZeros must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRotateRight], "RotateRight must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRotateLeft], "RotateLeft must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSignum], "Signum must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsInt], "AbsInt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsLong], "AbsLong must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsFloat], "AbsFloat must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsDouble], "AbsDouble must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxInt], "MinMaxInt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxLong], "MinMaxLong must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], "MinMaxFloat must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], "MinMaxDouble must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCos], "Cos must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSin], "Sin must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAcos], "Acos must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAsin], "Asin must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAtan], "Atan must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAtan2], "Atan2 must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCbrt], "Cbrt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCosh], "Cosh must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicExp], "Exp must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicExpm1], "Expm1 must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicHypot], "Hypot must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicLog], "Log must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicLog10], "Log10 must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNextAfter], "NextAfter must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSinh], "Sinh must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicTan], "Tan must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicTanh], "Tanh must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSqrt], "Sqrt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCeil], "Ceil must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloor], "Floor must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRint], "Rint must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRoundFloat], "RoundFloat must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRoundDouble], "RoundDouble must be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicReferenceGetReferent], "Get must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicCharAt], "CharAt must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicCompareTo], "CompareTo must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicEquals], "String equals must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicGetCharsNoCheck], "GetCharsNoCheck must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicIsEmptyOrLength], "IsEmptyOrLength must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicIndexOf], "IndexOf must not be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromBytes], - "NewStringFromBytes must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromChars], - "NewStringFromChars must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromString], - "NewStringFromString must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCurrentThread], "CurrentThread must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicPeek], "Peek must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicPoke], "Poke must be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicCas], "Cas must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGet], "UnsafeGet must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafePut], "UnsafePut must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddInt], "UnsafeGetAndAddInt must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddLong], "UnsafeGetAndAddLong must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetInt], "UnsafeGetAndSetInt must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetLong], "UnsafeGetAndSetLong must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetObject], "UnsafeGetAndSetObject must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeLoadFence], "UnsafeLoadFence must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeStoreFence], "UnsafeStoreFence must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeFullFence], "UnsafeFullFence must not be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopyCharArray], - "SystemArrayCopyCharArray must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopy], - "SystemArrayCopy must be static"); - -} // anonymous namespace - -const uint32_t DexFileMethodInliner::kIndexUnresolved; -const char* const DexFileMethodInliner::kClassCacheNames[] = { - "Z", // kClassCacheBoolean - "B", // kClassCacheByte - "C", // kClassCacheChar - "S", // kClassCacheShort - "I", // kClassCacheInt - "J", // kClassCacheLong - "F", // kClassCacheFloat - "D", // kClassCacheDouble - "V", // kClassCacheVoid - "[B", // kClassCacheJavaLangByteArray - "[C", // kClassCacheJavaLangCharArray - "[I", // kClassCacheJavaLangIntArray - "Ljava/lang/Object;", // kClassCacheJavaLangObject - "Ljava/lang/ref/Reference;", // kClassCacheJavaLangRefReference - "Ljava/lang/String;", // kClassCacheJavaLangString - "Ljava/lang/StringBuffer;", // kClassCacheJavaLangStringBuffer - "Ljava/lang/StringBuilder;", // kClassCacheJavaLangStringBuilder - "Ljava/lang/StringFactory;", // kClassCacheJavaLangStringFactory - "Ljava/lang/Double;", // kClassCacheJavaLangDouble - "Ljava/lang/Float;", // kClassCacheJavaLangFloat - "Ljava/lang/Integer;", // kClassCacheJavaLangInteger - "Ljava/lang/Long;", // kClassCacheJavaLangLong - "Ljava/lang/Short;", // kClassCacheJavaLangShort - "Ljava/lang/Math;", // kClassCacheJavaLangMath - "Ljava/lang/StrictMath;", // kClassCacheJavaLangStrictMath - "Ljava/lang/Thread;", // kClassCacheJavaLangThread - "Ljava/nio/charset/Charset;", // kClassCacheJavaNioCharsetCharset - "Llibcore/io/Memory;", // kClassCacheLibcoreIoMemory - "Lsun/misc/Unsafe;", // kClassCacheSunMiscUnsafe - "Ljava/lang/System;", // kClassCacheJavaLangSystem -}; - -const char* const DexFileMethodInliner::kNameCacheNames[] = { - "reverse", // kNameCacheReverse - "reverseBytes", // kNameCacheReverseBytes - "doubleToRawLongBits", // kNameCacheDoubleToRawLongBits - "longBitsToDouble", // kNameCacheLongBitsToDouble - "floatToRawIntBits", // kNameCacheFloatToRawIntBits - "intBitsToFloat", // kNameCacheIntBitsToFloat - "abs", // kNameCacheAbs - "max", // kNameCacheMax - "min", // kNameCacheMin - "cos", // kNameCacheCos - "sin", // kNameCacheSin - "acos", // kNameCacheAcos - "asin", // kNameCacheAsin - "atan", // kNameCacheAtan - "atan2", // kNameCacheAtan2 - "cbrt", // kNameCacheCbrt - "cosh", // kNameCacheCosh - "exp", // kNameCacheExp - "expm1", // kNameCacheExpm1 - "hypot", // kNameCacheHypot - "log", // kNameCacheLog - "log10", // kNameCacheLog10 - "nextAfter", // kNameCacheNextAfter - "sinh", // kNameCacheSinh - "tan", // kNameCacheTan - "tanh", // kNameCacheTanh - "sqrt", // kNameCacheSqrt - "ceil", // kNameCacheCeil - "floor", // kNameCacheFloor - "rint", // kNameCacheRint - "round", // kNameCacheRound - "getReferent", // kNameCacheReferenceGet - "charAt", // kNameCacheCharAt - "compareTo", // kNameCacheCompareTo - "equals", // kNameCacheEquals - "getCharsNoCheck", // kNameCacheGetCharsNoCheck - "isEmpty", // kNameCacheIsEmpty - "floatToIntBits", // kNameCacheFloatToIntBits - "doubleToLongBits", // kNameCacheDoubleToLongBits - "isInfinite", // kNameCacheIsInfinite - "isNaN", // kNameCacheIsNaN - "indexOf", // kNameCacheIndexOf - "length", // kNameCacheLength - "<init>", // kNameCacheInit - "newStringFromBytes", // kNameCacheNewStringFromBytes - "newStringFromChars", // kNameCacheNewStringFromChars - "newStringFromString", // kNameCacheNewStringFromString - "currentThread", // kNameCacheCurrentThread - "peekByte", // kNameCachePeekByte - "peekIntNative", // kNameCachePeekIntNative - "peekLongNative", // kNameCachePeekLongNative - "peekShortNative", // kNameCachePeekShortNative - "pokeByte", // kNameCachePokeByte - "pokeIntNative", // kNameCachePokeIntNative - "pokeLongNative", // kNameCachePokeLongNative - "pokeShortNative", // kNameCachePokeShortNative - "compareAndSwapInt", // kNameCacheCompareAndSwapInt - "compareAndSwapLong", // kNameCacheCompareAndSwapLong - "compareAndSwapObject", // kNameCacheCompareAndSwapObject - "getInt", // kNameCacheGetInt - "getIntVolatile", // kNameCacheGetIntVolatile - "putInt", // kNameCachePutInt - "putIntVolatile", // kNameCachePutIntVolatile - "putOrderedInt", // kNameCachePutOrderedInt - "getLong", // kNameCacheGetLong - "getLongVolatile", // kNameCacheGetLongVolatile - "putLong", // kNameCachePutLong - "putLongVolatile", // kNameCachePutLongVolatile - "putOrderedLong", // kNameCachePutOrderedLong - "getObject", // kNameCacheGetObject - "getObjectVolatile", // kNameCacheGetObjectVolatile - "putObject", // kNameCachePutObject - "putObjectVolatile", // kNameCachePutObjectVolatile - "putOrderedObject", // kNameCachePutOrderedObject - "getAndAddInt", // kNameCacheGetAndAddInt, - "getAndAddLong", // kNameCacheGetAndAddLong, - "getAndSetInt", // kNameCacheGetAndSetInt, - "getAndSetLong", // kNameCacheGetAndSetLong, - "getAndSetObject", // kNameCacheGetAndSetObject, - "loadFence", // kNameCacheLoadFence, - "storeFence", // kNameCacheStoreFence, - "fullFence", // kNameCacheFullFence, - "arraycopy", // kNameCacheArrayCopy - "bitCount", // kNameCacheBitCount - "compare", // kNameCacheCompare - "highestOneBit", // kNameCacheHighestOneBit - "lowestOneBit", // kNameCacheLowestOneBit - "numberOfLeadingZeros", // kNameCacheNumberOfLeadingZeros - "numberOfTrailingZeros", // kNameCacheNumberOfTrailingZeros - "rotateRight", // kNameCacheRotateRight - "rotateLeft", // kNameCacheRotateLeft - "signum", // kNameCacheSignum -}; - -const DexFileMethodInliner::ProtoDef DexFileMethodInliner::kProtoCacheDefs[] = { - // kProtoCacheI_I - { kClassCacheInt, 1, { kClassCacheInt } }, - // kProtoCacheJ_J - { kClassCacheLong, 1, { kClassCacheLong } }, - // kProtoCacheS_S - { kClassCacheShort, 1, { kClassCacheShort } }, - // kProtoCacheD_D - { kClassCacheDouble, 1, { kClassCacheDouble } }, - // kProtoCacheDD_D - { kClassCacheDouble, 2, { kClassCacheDouble, kClassCacheDouble } }, - // kProtoCacheF_F - { kClassCacheFloat, 1, { kClassCacheFloat } }, - // kProtoCacheFF_F - { kClassCacheFloat, 2, { kClassCacheFloat, kClassCacheFloat } }, - // kProtoCacheD_J - { kClassCacheLong, 1, { kClassCacheDouble } }, - // kProtoCacheD_Z - { kClassCacheBoolean, 1, { kClassCacheDouble } }, - // kProtoCacheJ_D - { kClassCacheDouble, 1, { kClassCacheLong } }, - // kProtoCacheF_I - { kClassCacheInt, 1, { kClassCacheFloat } }, - // kProtoCacheF_Z - { kClassCacheBoolean, 1, { kClassCacheFloat } }, - // kProtoCacheI_F - { kClassCacheFloat, 1, { kClassCacheInt } }, - // kProtoCacheII_I - { kClassCacheInt, 2, { kClassCacheInt, kClassCacheInt } }, - // kProtoCacheI_C - { kClassCacheChar, 1, { kClassCacheInt } }, - // kProtoCacheString_I - { kClassCacheInt, 1, { kClassCacheJavaLangString } }, - // kProtoCache_Z - { kClassCacheBoolean, 0, { } }, - // kProtoCache_I - { kClassCacheInt, 0, { } }, - // kProtoCache_Object - { kClassCacheJavaLangObject, 0, { } }, - // kProtoCache_Thread - { kClassCacheJavaLangThread, 0, { } }, - // kProtoCacheJ_B - { kClassCacheByte, 1, { kClassCacheLong } }, - // kProtoCacheJ_I - { kClassCacheInt, 1, { kClassCacheLong } }, - // kProtoCacheJ_S - { kClassCacheShort, 1, { kClassCacheLong } }, - // kProtoCacheJB_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheByte } }, - // kProtoCacheJI_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheInt } }, - // kProtoCacheJJ_J - { kClassCacheLong, 2, { kClassCacheLong, kClassCacheLong } }, - // kProtoCacheJJ_I - { kClassCacheInt, 2, { kClassCacheLong, kClassCacheLong } }, - // kProtoCacheJJ_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheLong } }, - // kProtoCacheJS_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheShort } }, - // kProtoCacheObject_Z - { kClassCacheBoolean, 1, { kClassCacheJavaLangObject } }, - // kProtoCacheJI_J - { kClassCacheLong, 2, { kClassCacheLong, kClassCacheInt } }, - // kProtoCacheObjectJII_Z - { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheInt, kClassCacheInt } }, - // kProtoCacheObjectJJJ_Z - { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheLong, kClassCacheLong } }, - // kProtoCacheObjectJObjectObject_Z - { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheJavaLangObject, kClassCacheJavaLangObject } }, - // kProtoCacheObjectJ_I - { kClassCacheInt, 2, { kClassCacheJavaLangObject, kClassCacheLong } }, - // kProtoCacheObjectJI_I - { kClassCacheInt, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } }, - // kProtoCacheObjectJI_V - { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } }, - // kProtoCacheObjectJ_J - { kClassCacheLong, 2, { kClassCacheJavaLangObject, kClassCacheLong } }, - // kProtoCacheObjectJJ_J - { kClassCacheLong, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } }, - // kProtoCacheObjectJJ_V - { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } }, - // kProtoCacheObjectJ_Object - { kClassCacheJavaLangObject, 2, { kClassCacheJavaLangObject, kClassCacheLong } }, - // kProtoCacheObjectJObject_V - { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheJavaLangObject } }, - // kProtoCacheObjectJObject_Object - { kClassCacheJavaLangObject, 3, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheJavaLangObject } }, - // kProtoCacheCharArrayICharArrayII_V - { kClassCacheVoid, 5, {kClassCacheJavaLangCharArray, kClassCacheInt, - kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt} }, - // kProtoCacheObjectIObjectII_V - { kClassCacheVoid, 5, {kClassCacheJavaLangObject, kClassCacheInt, - kClassCacheJavaLangObject, kClassCacheInt, kClassCacheInt} }, - // kProtoCacheIICharArrayI_V - { kClassCacheVoid, 4, { kClassCacheInt, kClassCacheInt, kClassCacheJavaLangCharArray, - kClassCacheInt } }, - // kProtoCacheByteArrayIII_String - { kClassCacheJavaLangString, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheInt } }, - // kProtoCacheIICharArray_String - { kClassCacheJavaLangString, 3, { kClassCacheInt, kClassCacheInt, - kClassCacheJavaLangCharArray } }, - // kProtoCacheString_String - { kClassCacheJavaLangString, 1, { kClassCacheJavaLangString } }, - // kProtoCache_V - { kClassCacheVoid, 0, { } }, - // kProtoCacheByteArray_V - { kClassCacheVoid, 1, { kClassCacheJavaLangByteArray } }, - // kProtoCacheByteArrayI_V - { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheInt } }, - // kProtoCacheByteArrayII_V - { kClassCacheVoid, 3, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt } }, - // kProtoCacheByteArrayIII_V - { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheInt } }, - // kProtoCacheByteArrayIIString_V - { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheJavaLangString } }, - // kProtoCacheByteArrayString_V - { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheJavaLangString } }, - // kProtoCacheByteArrayIICharset_V - { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheJavaNioCharsetCharset } }, - // kProtoCacheByteArrayCharset_V - { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheJavaNioCharsetCharset } }, - // kProtoCacheCharArray_V - { kClassCacheVoid, 1, { kClassCacheJavaLangCharArray } }, - // kProtoCacheCharArrayII_V - { kClassCacheVoid, 3, { kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt } }, - // kProtoCacheIICharArray_V - { kClassCacheVoid, 3, { kClassCacheInt, kClassCacheInt, kClassCacheJavaLangCharArray } }, - // kProtoCacheIntArrayII_V - { kClassCacheVoid, 3, { kClassCacheJavaLangIntArray, kClassCacheInt, kClassCacheInt } }, - // kProtoCacheString_V - { kClassCacheVoid, 1, { kClassCacheJavaLangString } }, - // kProtoCacheStringBuffer_V - { kClassCacheVoid, 1, { kClassCacheJavaLangStringBuffer } }, - // kProtoCacheStringBuilder_V - { kClassCacheVoid, 1, { kClassCacheJavaLangStringBuilder } }, -}; - -const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods[] = { -#define INTRINSIC(c, n, p, o, d) \ - { { kClassCache ## c, kNameCache ## n, kProtoCache ## p }, { o, kInlineIntrinsic, { d } } } - - INTRINSIC(JavaLangDouble, DoubleToRawLongBits, D_J, kIntrinsicDoubleCvt, 0), - INTRINSIC(JavaLangDouble, LongBitsToDouble, J_D, kIntrinsicDoubleCvt, kIntrinsicFlagToFloatingPoint), - INTRINSIC(JavaLangFloat, FloatToRawIntBits, F_I, kIntrinsicFloatCvt, 0), - INTRINSIC(JavaLangFloat, IntBitsToFloat, I_F, kIntrinsicFloatCvt, kIntrinsicFlagToFloatingPoint), - - INTRINSIC(JavaLangFloat, FloatToIntBits, F_I, kIntrinsicFloat2Int, 0), - INTRINSIC(JavaLangDouble, DoubleToLongBits, D_J, kIntrinsicDouble2Long, 0), - - INTRINSIC(JavaLangFloat, IsInfinite, F_Z, kIntrinsicFloatIsInfinite, 0), - INTRINSIC(JavaLangDouble, IsInfinite, D_Z, kIntrinsicDoubleIsInfinite, 0), - INTRINSIC(JavaLangFloat, IsNaN, F_Z, kIntrinsicFloatIsNaN, 0), - INTRINSIC(JavaLangDouble, IsNaN, D_Z, kIntrinsicDoubleIsNaN, 0), - - INTRINSIC(JavaLangInteger, ReverseBytes, I_I, kIntrinsicReverseBytes, k32), - INTRINSIC(JavaLangLong, ReverseBytes, J_J, kIntrinsicReverseBytes, k64), - INTRINSIC(JavaLangShort, ReverseBytes, S_S, kIntrinsicReverseBytes, kSignedHalf), - INTRINSIC(JavaLangInteger, Reverse, I_I, kIntrinsicReverseBits, k32), - INTRINSIC(JavaLangLong, Reverse, J_J, kIntrinsicReverseBits, k64), - - INTRINSIC(JavaLangInteger, BitCount, I_I, kIntrinsicBitCount, k32), - INTRINSIC(JavaLangLong, BitCount, J_I, kIntrinsicBitCount, k64), - INTRINSIC(JavaLangInteger, Compare, II_I, kIntrinsicCompare, k32), - INTRINSIC(JavaLangLong, Compare, JJ_I, kIntrinsicCompare, k64), - INTRINSIC(JavaLangInteger, HighestOneBit, I_I, kIntrinsicHighestOneBit, k32), - INTRINSIC(JavaLangLong, HighestOneBit, J_J, kIntrinsicHighestOneBit, k64), - INTRINSIC(JavaLangInteger, LowestOneBit, I_I, kIntrinsicLowestOneBit, k32), - INTRINSIC(JavaLangLong, LowestOneBit, J_J, kIntrinsicLowestOneBit, k64), - INTRINSIC(JavaLangInteger, NumberOfLeadingZeros, I_I, kIntrinsicNumberOfLeadingZeros, k32), - INTRINSIC(JavaLangLong, NumberOfLeadingZeros, J_I, kIntrinsicNumberOfLeadingZeros, k64), - INTRINSIC(JavaLangInteger, NumberOfTrailingZeros, I_I, kIntrinsicNumberOfTrailingZeros, k32), - INTRINSIC(JavaLangLong, NumberOfTrailingZeros, J_I, kIntrinsicNumberOfTrailingZeros, k64), - INTRINSIC(JavaLangInteger, Signum, I_I, kIntrinsicSignum, k32), - INTRINSIC(JavaLangLong, Signum, J_I, kIntrinsicSignum, k64), - - INTRINSIC(JavaLangMath, Abs, I_I, kIntrinsicAbsInt, 0), - INTRINSIC(JavaLangStrictMath, Abs, I_I, kIntrinsicAbsInt, 0), - INTRINSIC(JavaLangMath, Abs, J_J, kIntrinsicAbsLong, 0), - INTRINSIC(JavaLangStrictMath, Abs, J_J, kIntrinsicAbsLong, 0), - INTRINSIC(JavaLangMath, Abs, F_F, kIntrinsicAbsFloat, 0), - INTRINSIC(JavaLangStrictMath, Abs, F_F, kIntrinsicAbsFloat, 0), - INTRINSIC(JavaLangMath, Abs, D_D, kIntrinsicAbsDouble, 0), - INTRINSIC(JavaLangStrictMath, Abs, D_D, kIntrinsicAbsDouble, 0), - INTRINSIC(JavaLangMath, Min, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMax), - INTRINSIC(JavaLangMath, Min, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMax), - INTRINSIC(JavaLangMath, Min, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMax), - INTRINSIC(JavaLangMath, Min, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax), - - INTRINSIC(JavaLangMath, Cos, D_D, kIntrinsicCos, 0), - INTRINSIC(JavaLangMath, Sin, D_D, kIntrinsicSin, 0), - INTRINSIC(JavaLangMath, Acos, D_D, kIntrinsicAcos, 0), - INTRINSIC(JavaLangMath, Asin, D_D, kIntrinsicAsin, 0), - INTRINSIC(JavaLangMath, Atan, D_D, kIntrinsicAtan, 0), - INTRINSIC(JavaLangMath, Atan2, DD_D, kIntrinsicAtan2, 0), - INTRINSIC(JavaLangMath, Cbrt, D_D, kIntrinsicCbrt, 0), - INTRINSIC(JavaLangMath, Cosh, D_D, kIntrinsicCosh, 0), - INTRINSIC(JavaLangMath, Exp, D_D, kIntrinsicExp, 0), - INTRINSIC(JavaLangMath, Expm1, D_D, kIntrinsicExpm1, 0), - INTRINSIC(JavaLangMath, Hypot, DD_D, kIntrinsicHypot, 0), - INTRINSIC(JavaLangMath, Log, D_D, kIntrinsicLog, 0), - INTRINSIC(JavaLangMath, Log10, D_D, kIntrinsicLog10, 0), - INTRINSIC(JavaLangMath, NextAfter, DD_D, kIntrinsicNextAfter, 0), - INTRINSIC(JavaLangMath, Sinh, D_D, kIntrinsicSinh, 0), - INTRINSIC(JavaLangMath, Tan, D_D, kIntrinsicTan, 0), - INTRINSIC(JavaLangMath, Tanh, D_D, kIntrinsicTanh, 0), - INTRINSIC(JavaLangMath, Sqrt, D_D, kIntrinsicSqrt, 0), - INTRINSIC(JavaLangStrictMath, Sqrt, D_D, kIntrinsicSqrt, 0), - - INTRINSIC(JavaLangMath, Ceil, D_D, kIntrinsicCeil, 0), - INTRINSIC(JavaLangStrictMath, Ceil, D_D, kIntrinsicCeil, 0), - INTRINSIC(JavaLangMath, Floor, D_D, kIntrinsicFloor, 0), - INTRINSIC(JavaLangStrictMath, Floor, D_D, kIntrinsicFloor, 0), - INTRINSIC(JavaLangMath, Rint, D_D, kIntrinsicRint, 0), - INTRINSIC(JavaLangStrictMath, Rint, D_D, kIntrinsicRint, 0), - INTRINSIC(JavaLangMath, Round, F_I, kIntrinsicRoundFloat, 0), - INTRINSIC(JavaLangStrictMath, Round, F_I, kIntrinsicRoundFloat, 0), - INTRINSIC(JavaLangMath, Round, D_J, kIntrinsicRoundDouble, 0), - INTRINSIC(JavaLangStrictMath, Round, D_J, kIntrinsicRoundDouble, 0), - - INTRINSIC(JavaLangRefReference, ReferenceGetReferent, _Object, kIntrinsicReferenceGetReferent, 0), - - INTRINSIC(JavaLangString, CharAt, I_C, kIntrinsicCharAt, 0), - INTRINSIC(JavaLangString, CompareTo, String_I, kIntrinsicCompareTo, 0), - INTRINSIC(JavaLangString, Equals, Object_Z, kIntrinsicEquals, 0), - INTRINSIC(JavaLangString, GetCharsNoCheck, IICharArrayI_V, kIntrinsicGetCharsNoCheck, 0), - INTRINSIC(JavaLangString, IsEmpty, _Z, kIntrinsicIsEmptyOrLength, kIntrinsicFlagIsEmpty), - INTRINSIC(JavaLangString, IndexOf, II_I, kIntrinsicIndexOf, kIntrinsicFlagNone), - INTRINSIC(JavaLangString, IndexOf, I_I, kIntrinsicIndexOf, kIntrinsicFlagBase0), - INTRINSIC(JavaLangString, Length, _I, kIntrinsicIsEmptyOrLength, kIntrinsicFlagLength), - - INTRINSIC(JavaLangStringFactory, NewStringFromBytes, ByteArrayIII_String, - kIntrinsicNewStringFromBytes, kIntrinsicFlagNone), - INTRINSIC(JavaLangStringFactory, NewStringFromChars, IICharArray_String, - kIntrinsicNewStringFromChars, kIntrinsicFlagNone), - INTRINSIC(JavaLangStringFactory, NewStringFromString, String_String, - kIntrinsicNewStringFromString, kIntrinsicFlagNone), - - INTRINSIC(JavaLangThread, CurrentThread, _Thread, kIntrinsicCurrentThread, 0), - - INTRINSIC(LibcoreIoMemory, PeekByte, J_B, kIntrinsicPeek, kSignedByte), - INTRINSIC(LibcoreIoMemory, PeekIntNative, J_I, kIntrinsicPeek, k32), - INTRINSIC(LibcoreIoMemory, PeekLongNative, J_J, kIntrinsicPeek, k64), - INTRINSIC(LibcoreIoMemory, PeekShortNative, J_S, kIntrinsicPeek, kSignedHalf), - INTRINSIC(LibcoreIoMemory, PokeByte, JB_V, kIntrinsicPoke, kSignedByte), - INTRINSIC(LibcoreIoMemory, PokeIntNative, JI_V, kIntrinsicPoke, k32), - INTRINSIC(LibcoreIoMemory, PokeLongNative, JJ_V, kIntrinsicPoke, k64), - INTRINSIC(LibcoreIoMemory, PokeShortNative, JS_V, kIntrinsicPoke, kSignedHalf), - - INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas, - kIntrinsicFlagNone), - INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas, - kIntrinsicFlagIsLong), - INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas, - kIntrinsicFlagIsObject), - -#define UNSAFE_GET_PUT(type, code, type_flags) \ - INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \ - type_flags), \ - INTRINSIC(SunMiscUnsafe, Get ## type ## Volatile, ObjectJ_ ## code, kIntrinsicUnsafeGet, \ - (type_flags) | kIntrinsicFlagIsVolatile), \ - INTRINSIC(SunMiscUnsafe, Put ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \ - type_flags), \ - INTRINSIC(SunMiscUnsafe, Put ## type ## Volatile, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \ - (type_flags) | kIntrinsicFlagIsVolatile), \ - INTRINSIC(SunMiscUnsafe, PutOrdered ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \ - (type_flags) | kIntrinsicFlagIsOrdered) - - UNSAFE_GET_PUT(Int, I, kIntrinsicFlagNone), - UNSAFE_GET_PUT(Long, J, kIntrinsicFlagIsLong), - UNSAFE_GET_PUT(Object, Object, kIntrinsicFlagIsObject), -#undef UNSAFE_GET_PUT - - // 1.8 - INTRINSIC(SunMiscUnsafe, GetAndAddInt, ObjectJI_I, kIntrinsicUnsafeGetAndAddInt, 0), - INTRINSIC(SunMiscUnsafe, GetAndAddLong, ObjectJJ_J, kIntrinsicUnsafeGetAndAddLong, 0), - INTRINSIC(SunMiscUnsafe, GetAndSetInt, ObjectJI_I, kIntrinsicUnsafeGetAndSetInt, 0), - INTRINSIC(SunMiscUnsafe, GetAndSetLong, ObjectJJ_J, kIntrinsicUnsafeGetAndSetLong, 0), - INTRINSIC(SunMiscUnsafe, GetAndSetObject, ObjectJObject_Object, kIntrinsicUnsafeGetAndSetObject, 0), - INTRINSIC(SunMiscUnsafe, LoadFence, _V, kIntrinsicUnsafeLoadFence, 0), - INTRINSIC(SunMiscUnsafe, StoreFence, _V, kIntrinsicUnsafeStoreFence, 0), - INTRINSIC(SunMiscUnsafe, FullFence, _V, kIntrinsicUnsafeFullFence, 0), - - INTRINSIC(JavaLangSystem, ArrayCopy, CharArrayICharArrayII_V , kIntrinsicSystemArrayCopyCharArray, - 0), - INTRINSIC(JavaLangSystem, ArrayCopy, ObjectIObjectII_V , kIntrinsicSystemArrayCopy, - 0), - - INTRINSIC(JavaLangInteger, RotateRight, II_I, kIntrinsicRotateRight, k32), - INTRINSIC(JavaLangLong, RotateRight, JI_J, kIntrinsicRotateRight, k64), - INTRINSIC(JavaLangInteger, RotateLeft, II_I, kIntrinsicRotateLeft, k32), - INTRINSIC(JavaLangLong, RotateLeft, JI_J, kIntrinsicRotateLeft, k64), - -#undef INTRINSIC -}; - -DexFileMethodInliner::DexFileMethodInliner() - : lock_("DexFileMethodInliner lock", kDexFileMethodInlinerLock), - dex_file_(nullptr) { - static_assert(kClassCacheFirst == 0, "kClassCacheFirst not 0"); - static_assert(arraysize(kClassCacheNames) == kClassCacheLast, - "bad arraysize for kClassCacheNames"); - static_assert(kNameCacheFirst == 0, "kNameCacheFirst not 0"); - static_assert(arraysize(kNameCacheNames) == kNameCacheLast, - "bad arraysize for kNameCacheNames"); - static_assert(kProtoCacheFirst == 0, "kProtoCacheFirst not 0"); - static_assert(arraysize(kProtoCacheDefs) == kProtoCacheLast, - "bad arraysize kProtoCacheNames"); -} - -DexFileMethodInliner::~DexFileMethodInliner() { -} - -bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) { - InlineMethod method; - bool success = InlineMethodAnalyser::AnalyseMethodCode(verifier, &method); - return success && AddInlineMethod(verifier->GetMethodReference().dex_method_index, method); -} - -InlineMethodFlags DexFileMethodInliner::IsIntrinsicOrSpecial(uint32_t method_index) { - ReaderMutexLock mu(Thread::Current(), lock_); - auto it = inline_methods_.find(method_index); - if (it != inline_methods_.end()) { - DCHECK_NE(it->second.flags & (kInlineIntrinsic | kInlineSpecial), 0); - return it->second.flags; - } else { - return kNoInlineMethodFlags; - } -} - -bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) { - ReaderMutexLock mu(Thread::Current(), lock_); - auto it = inline_methods_.find(method_index); - bool res = (it != inline_methods_.end() && (it->second.flags & kInlineIntrinsic) != 0); - if (res && intrinsic != nullptr) { - *intrinsic = it->second; - } - return res; -} - -bool DexFileMethodInliner::IsSpecial(uint32_t method_index) { - ReaderMutexLock mu(Thread::Current(), lock_); - auto it = inline_methods_.find(method_index); - return it != inline_methods_.end() && (it->second.flags & kInlineSpecial) != 0; -} - -uint32_t DexFileMethodInliner::FindClassIndex(const DexFile* dex_file, IndexCache* cache, - ClassCacheIndex index) { - uint32_t* class_index = &cache->class_indexes[index]; - if (*class_index != kIndexUnresolved) { - return *class_index; - } - - const DexFile::TypeId* type_id = dex_file->FindTypeId(kClassCacheNames[index]); - if (type_id == nullptr) { - *class_index = kIndexNotFound; - return *class_index; - } - *class_index = dex_file->GetIndexForTypeId(*type_id); - return *class_index; -} - -uint32_t DexFileMethodInliner::FindNameIndex(const DexFile* dex_file, IndexCache* cache, - NameCacheIndex index) { - uint32_t* name_index = &cache->name_indexes[index]; - if (*name_index != kIndexUnresolved) { - return *name_index; - } - - const DexFile::StringId* string_id = dex_file->FindStringId(kNameCacheNames[index]); - if (string_id == nullptr) { - *name_index = kIndexNotFound; - return *name_index; - } - *name_index = dex_file->GetIndexForStringId(*string_id); - return *name_index; -} - -uint32_t DexFileMethodInliner::FindProtoIndex(const DexFile* dex_file, IndexCache* cache, - ProtoCacheIndex index) { - uint32_t* proto_index = &cache->proto_indexes[index]; - if (*proto_index != kIndexUnresolved) { - return *proto_index; - } - - const ProtoDef& proto_def = kProtoCacheDefs[index]; - uint32_t return_index = FindClassIndex(dex_file, cache, proto_def.return_type); - if (return_index == kIndexNotFound) { - *proto_index = kIndexNotFound; - return *proto_index; - } - uint16_t return_type = static_cast<uint16_t>(return_index); - DCHECK_EQ(static_cast<uint32_t>(return_type), return_index); - - uint32_t signature_length = proto_def.param_count; - uint16_t signature_type_idxs[kProtoMaxParams]; - for (uint32_t i = 0; i != signature_length; ++i) { - uint32_t param_index = FindClassIndex(dex_file, cache, proto_def.params[i]); - if (param_index == kIndexNotFound) { - *proto_index = kIndexNotFound; - return *proto_index; - } - signature_type_idxs[i] = static_cast<uint16_t>(param_index); - DCHECK_EQ(static_cast<uint32_t>(signature_type_idxs[i]), param_index); - } - - const DexFile::ProtoId* proto_id = dex_file->FindProtoId(return_type, signature_type_idxs, - signature_length); - if (proto_id == nullptr) { - *proto_index = kIndexNotFound; - return *proto_index; - } - *proto_index = dex_file->GetIndexForProtoId(*proto_id); - return *proto_index; -} - -uint32_t DexFileMethodInliner::FindMethodIndex(const DexFile* dex_file, IndexCache* cache, - const MethodDef& method_def) { - uint32_t declaring_class_index = FindClassIndex(dex_file, cache, method_def.declaring_class); - if (declaring_class_index == kIndexNotFound) { - return kIndexNotFound; - } - uint32_t name_index = FindNameIndex(dex_file, cache, method_def.name); - if (name_index == kIndexNotFound) { - return kIndexNotFound; - } - uint32_t proto_index = FindProtoIndex(dex_file, cache, method_def.proto); - if (proto_index == kIndexNotFound) { - return kIndexNotFound; - } - const DexFile::MethodId* method_id = - dex_file->FindMethodId(dex_file->GetTypeId(declaring_class_index), - dex_file->GetStringId(name_index), - dex_file->GetProtoId(proto_index)); - if (method_id == nullptr) { - return kIndexNotFound; - } - return dex_file->GetIndexForMethodId(*method_id); -} - -DexFileMethodInliner::IndexCache::IndexCache() { - std::fill_n(class_indexes, arraysize(class_indexes), kIndexUnresolved); - std::fill_n(name_indexes, arraysize(name_indexes), kIndexUnresolved); - std::fill_n(proto_indexes, arraysize(proto_indexes), kIndexUnresolved); -} - -void DexFileMethodInliner::FindIntrinsics(const DexFile* dex_file) { - DCHECK(dex_file != nullptr); - DCHECK(dex_file_ == nullptr); - IndexCache cache; - for (const IntrinsicDef& def : kIntrinsicMethods) { - uint32_t method_idx = FindMethodIndex(dex_file, &cache, def.method_def); - if (method_idx != kIndexNotFound) { - DCHECK(inline_methods_.find(method_idx) == inline_methods_.end()); - inline_methods_.Put(method_idx, def.intrinsic); - } - } - dex_file_ = dex_file; -} - -bool DexFileMethodInliner::AddInlineMethod(int32_t method_idx, const InlineMethod& method) { - WriterMutexLock mu(Thread::Current(), lock_); - if (LIKELY(inline_methods_.find(method_idx) == inline_methods_.end())) { - inline_methods_.Put(method_idx, method); - return true; - } else { - if (PrettyMethod(method_idx, *dex_file_) == "int java.lang.String.length()") { - // TODO: String.length is both kIntrinsicIsEmptyOrLength and kInlineOpIGet. - } else { - LOG(WARNING) << "Inliner: " << PrettyMethod(method_idx, *dex_file_) << " already inline"; - } - return false; - } -} - -} // namespace art diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h deleted file mode 100644 index f4ae5a548e..0000000000 --- a/compiler/dex/quick/dex_file_method_inliner.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_ -#define ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_ - -#include <stdint.h> - -#include "base/enums.h" -#include "base/mutex.h" -#include "base/macros.h" -#include "safe_map.h" -#include "dex_file.h" -#include "quick/inline_method_analyser.h" - -namespace art { - -namespace verifier { -class MethodVerifier; -} // namespace verifier - -enum OpSize { - k32, - k64, - kSignedHalf, - kSignedByte, -}; - -/** - * Handles inlining of methods from a particular DexFile. - * - * Intrinsics are a special case of inline methods. The DexFile indices for - * all the supported intrinsic methods are looked up once by the FindIntrinsics - * function and cached by this class for quick lookup by the method index. - * - * TODO: Detect short methods (at least getters, setters and empty functions) - * from the verifier and mark them for inlining. Inline these methods early - * during compilation to allow further optimizations. Similarly, provide - * additional information about intrinsics to the early phases of compilation. - */ -class DexFileMethodInliner { - public: - DexFileMethodInliner(); - ~DexFileMethodInliner(); - - /** - * Analyse method code to determine if the method is a candidate for inlining. - * If it is, record its data for later. - * - * @param verifier the method verifier holding data about the method to analyse. - * @return true if the method is a candidate for inlining, false otherwise. - */ - bool AnalyseMethodCode(verifier::MethodVerifier* verifier) - REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!lock_); - - /** - * Check whether a particular method index corresponds to an intrinsic or special function. - */ - InlineMethodFlags IsIntrinsicOrSpecial(uint32_t method_index) REQUIRES(!lock_); - - /** - * Check whether a particular method index corresponds to an intrinsic function. - */ - bool IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) REQUIRES(!lock_); - - /** - * Check whether a particular method index corresponds to a special function. - */ - bool IsSpecial(uint32_t method_index) REQUIRES(!lock_); - - /** - * To avoid multiple lookups of a class by its descriptor, we cache its - * type index in the IndexCache. These are the indexes into the IndexCache - * class_indexes array. - */ - enum ClassCacheIndex : uint8_t { // unit8_t to save space, make larger if needed - kClassCacheFirst = 0, - kClassCacheBoolean = kClassCacheFirst, - kClassCacheByte, - kClassCacheChar, - kClassCacheShort, - kClassCacheInt, - kClassCacheLong, - kClassCacheFloat, - kClassCacheDouble, - kClassCacheVoid, - kClassCacheJavaLangByteArray, - kClassCacheJavaLangCharArray, - kClassCacheJavaLangIntArray, - kClassCacheJavaLangObject, - kClassCacheJavaLangRefReference, - kClassCacheJavaLangString, - kClassCacheJavaLangStringBuffer, - kClassCacheJavaLangStringBuilder, - kClassCacheJavaLangStringFactory, - kClassCacheJavaLangDouble, - kClassCacheJavaLangFloat, - kClassCacheJavaLangInteger, - kClassCacheJavaLangLong, - kClassCacheJavaLangShort, - kClassCacheJavaLangMath, - kClassCacheJavaLangStrictMath, - kClassCacheJavaLangThread, - kClassCacheJavaNioCharsetCharset, - kClassCacheLibcoreIoMemory, - kClassCacheSunMiscUnsafe, - kClassCacheJavaLangSystem, - kClassCacheLast - }; - - /** - * To avoid multiple lookups of a method name string, we cache its string - * index in the IndexCache. These are the indexes into the IndexCache - * name_indexes array. - */ - enum NameCacheIndex : uint8_t { // unit8_t to save space, make larger if needed - kNameCacheFirst = 0, - kNameCacheReverse = kNameCacheFirst, - kNameCacheReverseBytes, - kNameCacheDoubleToRawLongBits, - kNameCacheLongBitsToDouble, - kNameCacheFloatToRawIntBits, - kNameCacheIntBitsToFloat, - kNameCacheAbs, - kNameCacheMax, - kNameCacheMin, - kNameCacheCos, - kNameCacheSin, - kNameCacheAcos, - kNameCacheAsin, - kNameCacheAtan, - kNameCacheAtan2, - kNameCacheCbrt, - kNameCacheCosh, - kNameCacheExp, - kNameCacheExpm1, - kNameCacheHypot, - kNameCacheLog, - kNameCacheLog10, - kNameCacheNextAfter, - kNameCacheSinh, - kNameCacheTan, - kNameCacheTanh, - kNameCacheSqrt, - kNameCacheCeil, - kNameCacheFloor, - kNameCacheRint, - kNameCacheRound, - kNameCacheReferenceGetReferent, - kNameCacheCharAt, - kNameCacheCompareTo, - kNameCacheEquals, - kNameCacheGetCharsNoCheck, - kNameCacheIsEmpty, - kNameCacheFloatToIntBits, - kNameCacheDoubleToLongBits, - kNameCacheIsInfinite, - kNameCacheIsNaN, - kNameCacheIndexOf, - kNameCacheLength, - kNameCacheInit, - kNameCacheNewStringFromBytes, - kNameCacheNewStringFromChars, - kNameCacheNewStringFromString, - kNameCacheCurrentThread, - kNameCachePeekByte, - kNameCachePeekIntNative, - kNameCachePeekLongNative, - kNameCachePeekShortNative, - kNameCachePokeByte, - kNameCachePokeIntNative, - kNameCachePokeLongNative, - kNameCachePokeShortNative, - kNameCacheCompareAndSwapInt, - kNameCacheCompareAndSwapLong, - kNameCacheCompareAndSwapObject, - kNameCacheGetInt, - kNameCacheGetIntVolatile, - kNameCachePutInt, - kNameCachePutIntVolatile, - kNameCachePutOrderedInt, - kNameCacheGetLong, - kNameCacheGetLongVolatile, - kNameCachePutLong, - kNameCachePutLongVolatile, - kNameCachePutOrderedLong, - kNameCacheGetObject, - kNameCacheGetObjectVolatile, - kNameCachePutObject, - kNameCachePutObjectVolatile, - kNameCachePutOrderedObject, - kNameCacheGetAndAddInt, - kNameCacheGetAndAddLong, - kNameCacheGetAndSetInt, - kNameCacheGetAndSetLong, - kNameCacheGetAndSetObject, - kNameCacheLoadFence, - kNameCacheStoreFence, - kNameCacheFullFence, - kNameCacheArrayCopy, - kNameCacheBitCount, - kNameCacheCompare, - kNameCacheHighestOneBit, - kNameCacheLowestOneBit, - kNameCacheNumberOfLeadingZeros, - kNameCacheNumberOfTrailingZeros, - kNameCacheRotateRight, - kNameCacheRotateLeft, - kNameCacheSignum, - kNameCacheLast - }; - - /** - * To avoid multiple lookups of a method signature, we cache its proto - * index in the IndexCache. These are the indexes into the IndexCache - * proto_indexes array. - */ - enum ProtoCacheIndex : uint8_t { // unit8_t to save space, make larger if needed - kProtoCacheFirst = 0, - kProtoCacheI_I = kProtoCacheFirst, - kProtoCacheJ_J, - kProtoCacheS_S, - kProtoCacheD_D, - kProtoCacheDD_D, - kProtoCacheF_F, - kProtoCacheFF_F, - kProtoCacheD_J, - kProtoCacheD_Z, - kProtoCacheJ_D, - kProtoCacheF_I, - kProtoCacheF_Z, - kProtoCacheI_F, - kProtoCacheII_I, - kProtoCacheI_C, - kProtoCacheString_I, - kProtoCache_Z, - kProtoCache_I, - kProtoCache_Object, - kProtoCache_Thread, - kProtoCacheJ_B, - kProtoCacheJ_I, - kProtoCacheJ_S, - kProtoCacheJB_V, - kProtoCacheJI_V, - kProtoCacheJJ_J, - kProtoCacheJJ_I, - kProtoCacheJJ_V, - kProtoCacheJS_V, - kProtoCacheObject_Z, - kProtoCacheJI_J, - kProtoCacheObjectJII_Z, - kProtoCacheObjectJJJ_Z, - kProtoCacheObjectJObjectObject_Z, - kProtoCacheObjectJ_I, - kProtoCacheObjectJI_I, - kProtoCacheObjectJI_V, - kProtoCacheObjectJ_J, - kProtoCacheObjectJJ_J, - kProtoCacheObjectJJ_V, - kProtoCacheObjectJ_Object, - kProtoCacheObjectJObject_V, - kProtoCacheObjectJObject_Object, - kProtoCacheCharArrayICharArrayII_V, - kProtoCacheObjectIObjectII_V, - kProtoCacheIICharArrayI_V, - kProtoCacheByteArrayIII_String, - kProtoCacheIICharArray_String, - kProtoCacheString_String, - kProtoCache_V, - kProtoCacheByteArray_V, - kProtoCacheByteArrayI_V, - kProtoCacheByteArrayII_V, - kProtoCacheByteArrayIII_V, - kProtoCacheByteArrayIIString_V, - kProtoCacheByteArrayString_V, - kProtoCacheByteArrayIICharset_V, - kProtoCacheByteArrayCharset_V, - kProtoCacheCharArray_V, - kProtoCacheCharArrayII_V, - kProtoCacheIICharArray_V, - kProtoCacheIntArrayII_V, - kProtoCacheString_V, - kProtoCacheStringBuffer_V, - kProtoCacheStringBuilder_V, - kProtoCacheLast - }; - - private: - /** - * The maximum number of method parameters we support in the ProtoDef. - */ - static constexpr uint32_t kProtoMaxParams = 6; - - /** - * The method signature (proto) definition using cached class indexes. - * The return_type and params are used with the IndexCache to look up - * appropriate class indexes to be passed to DexFile::FindProtoId(). - */ - struct ProtoDef { - ClassCacheIndex return_type; - uint8_t param_count; - ClassCacheIndex params[kProtoMaxParams]; - }; - - /** - * The method definition using cached class, name and proto indexes. - * The class index, method name index and proto index are used with - * IndexCache to look up appropriate parameters for DexFile::FindMethodId(). - */ - struct MethodDef { - ClassCacheIndex declaring_class; - NameCacheIndex name; - ProtoCacheIndex proto; - }; - - /** - * The definition of an intrinsic function binds the method definition - * to an Intrinsic. - */ - struct IntrinsicDef { - MethodDef method_def; - InlineMethod intrinsic; - }; - - /** - * Cache for class, method name and method signature indexes used during - * intrinsic function lookup to avoid multiple lookups of the same items. - * - * Many classes have multiple intrinsics and/or they are used in multiple - * method signatures and we want to avoid repeated lookups since they are - * not exactly cheap. The method names and method signatures are sometimes - * reused and therefore cached as well. - */ - struct IndexCache { - IndexCache(); - - uint32_t class_indexes[kClassCacheLast - kClassCacheFirst]; - uint32_t name_indexes[kNameCacheLast - kNameCacheFirst]; - uint32_t proto_indexes[kProtoCacheLast - kProtoCacheFirst]; - }; - - static const char* const kClassCacheNames[]; - static const char* const kNameCacheNames[]; - static const ProtoDef kProtoCacheDefs[]; - static const IntrinsicDef kIntrinsicMethods[]; - - static const uint32_t kIndexNotFound = static_cast<uint32_t>(-1); - static const uint32_t kIndexUnresolved = static_cast<uint32_t>(-2); - - static uint32_t FindClassIndex(const DexFile* dex_file, IndexCache* cache, - ClassCacheIndex index); - static uint32_t FindNameIndex(const DexFile* dex_file, IndexCache* cache, - NameCacheIndex index); - static uint32_t FindProtoIndex(const DexFile* dex_file, IndexCache* cache, - ProtoCacheIndex index); - static uint32_t FindMethodIndex(const DexFile* dex_file, IndexCache* cache, - const MethodDef& method_def); - - /** - * Find all known intrinsic methods in the dex_file and cache their indices. - * - * Only DexFileToMethodInlinerMap may call this function to initialize the inliner. - */ - void FindIntrinsics(const DexFile* dex_file) REQUIRES(lock_); - - friend class DexFileToMethodInlinerMap; - - bool AddInlineMethod(int32_t method_idx, const InlineMethod& method) REQUIRES(!lock_); - - ReaderWriterMutex lock_; - /* - * Maps method indexes (for the particular DexFile) to Intrinsic defintions. - */ - SafeMap<uint32_t, InlineMethod> inline_methods_ GUARDED_BY(lock_); - const DexFile* dex_file_; - - DISALLOW_COPY_AND_ASSIGN(DexFileMethodInliner); -}; - -} // namespace art - -#endif // ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_ diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.cc b/compiler/dex/quick/dex_file_to_method_inliner_map.cc deleted file mode 100644 index 2fec183289..0000000000 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> -#include <utility> -#include "thread.h" -#include "thread-inl.h" -#include "base/mutex.h" -#include "base/mutex-inl.h" -#include "base/logging.h" -#include "driver/compiler_driver.h" - -#include "dex_file_to_method_inliner_map.h" - -namespace art { - -DexFileToMethodInlinerMap::DexFileToMethodInlinerMap() - : lock_("DexFileToMethodInlinerMap lock", kDexFileToMethodInlinerMapLock) { -} - -DexFileToMethodInlinerMap::~DexFileToMethodInlinerMap() { - for (auto& entry : inliners_) { - delete entry.second; - } -} - -DexFileMethodInliner* DexFileToMethodInlinerMap::GetMethodInliner(const DexFile* dex_file) { - Thread* self = Thread::Current(); - { - ReaderMutexLock mu(self, lock_); - auto it = inliners_.find(dex_file); - if (it != inliners_.end()) { - return it->second; - } - } - - // We need to acquire our lock_ to modify inliners_ but we want to release it - // before we initialize the new inliner. However, we need to acquire the - // new inliner's lock_ before we release our lock_ to prevent another thread - // from using the uninitialized inliner. This requires explicit calls to - // ExclusiveLock()/ExclusiveUnlock() on one of the locks, the other one - // can use WriterMutexLock. - DexFileMethodInliner* locked_inliner; - { - WriterMutexLock mu(self, lock_); - DexFileMethodInliner** inliner = &inliners_[dex_file]; // inserts new entry if not found - if (*inliner) { - return *inliner; - } - *inliner = new DexFileMethodInliner; - DCHECK(*inliner != nullptr); - locked_inliner = *inliner; - locked_inliner->lock_.ExclusiveLock(self); // Acquire inliner's lock_ before releasing lock_. - } - locked_inliner->FindIntrinsics(dex_file); - locked_inliner->lock_.ExclusiveUnlock(self); - return locked_inliner; -} - -} // namespace art diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.h b/compiler/dex/quick/dex_file_to_method_inliner_map.h deleted file mode 100644 index 215dc12b26..0000000000 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_DEX_QUICK_DEX_FILE_TO_METHOD_INLINER_MAP_H_ -#define ART_COMPILER_DEX_QUICK_DEX_FILE_TO_METHOD_INLINER_MAP_H_ - -#include <map> -#include <vector> -#include "base/macros.h" -#include "base/mutex.h" - -#include "dex/quick/dex_file_method_inliner.h" - -namespace art { - -class CompilerDriver; -class DexFile; - -/** - * Map each DexFile to its DexFileMethodInliner. - * - * The method inliner is created and initialized the first time it's requested - * for a particular DexFile. - */ -class DexFileToMethodInlinerMap { - public: - DexFileToMethodInlinerMap(); - ~DexFileToMethodInlinerMap(); - - DexFileMethodInliner* GetMethodInliner(const DexFile* dex_file) NO_THREAD_SAFETY_ANALYSIS; - // TODO: There is an irregular non-scoped use of locks that defeats annotalysis with -O0. - // Fix the NO_THREAD_SAFETY_ANALYSIS when this works and add the appropriate LOCKS_EXCLUDED. - - private: - ReaderWriterMutex lock_; - std::map<const DexFile*, DexFileMethodInliner*> inliners_ GUARDED_BY(lock_); - - DISALLOW_COPY_AND_ASSIGN(DexFileToMethodInlinerMap); -}; - -} // namespace art - -#endif // ART_COMPILER_DEX_QUICK_DEX_FILE_TO_METHOD_INLINER_MAP_H_ diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc index 2532bda632..932eb51aee 100644 --- a/compiler/dex/quick_compiler_callbacks.cc +++ b/compiler/dex/quick_compiler_callbacks.cc @@ -16,7 +16,6 @@ #include "quick_compiler_callbacks.h" -#include "quick/dex_file_to_method_inliner_map.h" #include "verifier/method_verifier-inl.h" #include "verification_results.h" @@ -24,8 +23,6 @@ namespace art { void QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) { verification_results_->ProcessVerifiedMethod(verifier); - MethodReference ref = verifier->GetMethodReference(); - method_inliner_map_->GetMethodInliner(ref.dex_file)->AnalyseMethodCode(verifier); } void QuickCompilerCallbacks::ClassRejected(ClassReference ref) { diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h index 824194c7bd..34fd88b498 100644 --- a/compiler/dex/quick_compiler_callbacks.h +++ b/compiler/dex/quick_compiler_callbacks.h @@ -22,19 +22,15 @@ namespace art { class VerificationResults; -class DexFileToMethodInlinerMap; class QuickCompilerCallbacks FINAL : public CompilerCallbacks { public: QuickCompilerCallbacks(VerificationResults* verification_results, - DexFileToMethodInlinerMap* method_inliner_map, CompilerCallbacks::CallbackMode mode) : CompilerCallbacks(mode), verification_results_(verification_results), - method_inliner_map_(method_inliner_map), verifier_deps_(nullptr) { CHECK(verification_results != nullptr); - CHECK(method_inliner_map != nullptr); } ~QuickCompilerCallbacks() { } @@ -59,7 +55,6 @@ class QuickCompilerCallbacks FINAL : public CompilerCallbacks { private: VerificationResults* const verification_results_; - DexFileToMethodInlinerMap* const method_inliner_map_; verifier::VerifierDeps* verifier_deps_; }; diff --git a/compiler/driver/compiled_method_storage_test.cc b/compiler/driver/compiled_method_storage_test.cc index 6863f42d11..5063d716d5 100644 --- a/compiler/driver/compiled_method_storage_test.cc +++ b/compiler/driver/compiled_method_storage_test.cc @@ -21,17 +21,14 @@ #include "compiler_driver.h" #include "compiler_options.h" #include "dex/verification_results.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" namespace art { TEST(CompiledMethodStorage, Deduplicate) { CompilerOptions compiler_options; VerificationResults verification_results(&compiler_options); - DexFileToMethodInlinerMap method_inliner_map; CompilerDriver driver(&compiler_options, &verification_results, - &method_inliner_map, Compiler::kOptimizing, /* instruction_set_ */ kNone, /* instruction_set_features */ nullptr, diff --git a/compiler/driver/compiler_driver-inl.h b/compiler/driver/compiler_driver-inl.h index 4b913f4255..2d0dd3cda2 100644 --- a/compiler/driver/compiler_driver-inl.h +++ b/compiler/driver/compiler_driver-inl.h @@ -26,7 +26,7 @@ #include "dex_compilation_unit.h" #include "mirror/class_loader.h" #include "mirror/dex_cache-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "handle_scope-inl.h" namespace art { @@ -37,7 +37,7 @@ inline mirror::DexCache* CompilerDriver::GetDexCache(const DexCompilationUnit* m inline mirror::ClassLoader* CompilerDriver::GetClassLoader(const ScopedObjectAccess& soa, const DexCompilationUnit* mUnit) { - return soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()); + return soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()).Decode(); } inline mirror::Class* CompilerDriver::ResolveClass( @@ -45,7 +45,7 @@ inline mirror::Class* CompilerDriver::ResolveClass( Handle<mirror::ClassLoader> class_loader, uint16_t cls_index, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); - DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); mirror::Class* cls = mUnit->GetClassLinker()->ResolveType( *mUnit->GetDexFile(), cls_index, dex_cache, class_loader); DCHECK_EQ(cls == nullptr, soa.Self()->IsExceptionPending()); @@ -60,7 +60,7 @@ inline mirror::Class* CompilerDriver::ResolveCompilingMethodsClass( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit) { DCHECK_EQ(dex_cache->GetDexFile(), mUnit->GetDexFile()); - DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); const DexFile::MethodId& referrer_method_id = mUnit->GetDexFile()->GetMethodId(mUnit->GetDexMethodIndex()); return ResolveClass(soa, dex_cache, class_loader, referrer_method_id.class_idx_, mUnit); @@ -95,7 +95,7 @@ inline ArtField* CompilerDriver::ResolveField( const ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t field_idx, bool is_static) { - DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); return ResolveFieldWithDexFile(soa, dex_cache, class_loader, mUnit->GetDexFile(), field_idx, is_static); } @@ -258,7 +258,7 @@ inline ArtMethod* CompilerDriver::ResolveMethod( ScopedObjectAccess& soa, Handle<mirror::DexCache> dex_cache, Handle<mirror::ClassLoader> class_loader, const DexCompilationUnit* mUnit, uint32_t method_idx, InvokeType invoke_type, bool check_incompatible_class_change) { - DCHECK_EQ(class_loader.Get(), soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader())); + DCHECK_EQ(class_loader.Get(), GetClassLoader(soa, mUnit)); ArtMethod* resolved_method = check_incompatible_class_change ? mUnit->GetClassLinker()->ResolveMethod<ClassLinker::kForceICCECheck>( diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index f1d3116acd..2ec3f164e3 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -44,9 +44,8 @@ #include "dex/dex_to_dex_compiler.h" #include "dex/verification_results.h" #include "dex/verified_method.h" -#include "dex/quick/dex_file_method_inliner.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_options.h" +#include "intrinsics_enum.h" #include "jni_internal.h" #include "object_lock.h" #include "runtime.h" @@ -60,7 +59,7 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "mirror/throwable.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "handle_scope-inl.h" #include "thread.h" @@ -353,7 +352,6 @@ class CompilerDriver::DexFileMethodSet { CompilerDriver::CompilerDriver( const CompilerOptions* compiler_options, VerificationResults* verification_results, - DexFileToMethodInlinerMap* method_inliner_map, Compiler::Kind compiler_kind, InstructionSet instruction_set, const InstructionSetFeatures* instruction_set_features, @@ -370,7 +368,6 @@ CompilerDriver::CompilerDriver( const ProfileCompilationInfo* profile_compilation_info) : compiler_options_(compiler_options), verification_results_(verification_results), - method_inliner_map_(method_inliner_map), compiler_(Compiler::Create(this, compiler_kind)), compiler_kind_(compiler_kind), instruction_set_(instruction_set == kArm ? kThumb2: instruction_set), @@ -401,7 +398,6 @@ CompilerDriver::CompilerDriver( dex_to_dex_references_(), current_dex_to_dex_methods_(nullptr) { DCHECK(compiler_options_ != nullptr); - DCHECK(method_inliner_map_ != nullptr); compiler_->Init(); @@ -463,6 +459,29 @@ std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickToInterpr } #undef CREATE_TRAMPOLINE +static void SetupIntrinsic(Thread* self, + Intrinsics intrinsic, + InvokeType invoke_type, + const char* class_name, + const char* method_name, + const char* signature) + REQUIRES_SHARED(Locks::mutator_lock_) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + PointerSize image_size = class_linker->GetImagePointerSize(); + mirror::Class* cls = class_linker->FindSystemClass(self, class_name); + if (cls == nullptr) { + LOG(FATAL) << "Could not find class of intrinsic " << class_name; + } + ArtMethod* method = (invoke_type == kStatic || invoke_type == kDirect) + ? cls->FindDeclaredDirectMethod(method_name, signature, image_size) + : cls->FindDeclaredVirtualMethod(method_name, signature, image_size); + if (method == nullptr) { + LOG(FATAL) << "Could not find method of intrinsic " << class_name << method_name << signature; + } + DCHECK_EQ(method->GetInvokeType(), invoke_type); + method->SetIntrinsic(static_cast<uint32_t>(intrinsic)); +} + void CompilerDriver::CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings) { @@ -477,6 +496,17 @@ void CompilerDriver::CompileAll(jobject class_loader, // 3) Attempt to verify all classes // 4) Attempt to initialize image classes, and trivially initialized classes PreCompile(class_loader, dex_files, timings); + if (IsBootImage()) { + // We don't need to setup the intrinsics for non boot image compilation, as + // those compilations will pick up a boot image that have the ArtMethod already + // set with the intrinsics flag. + ScopedObjectAccess soa(Thread::Current()); +#define OPTIMIZING_INTRINSICS(Name, InvokeType, NeedsEnvironmentOrCache, SideEffects, Exceptions, ClassName, MethodName, Signature) \ + SetupIntrinsic(soa.Self(), Intrinsics::k##Name, InvokeType, ClassName, MethodName, Signature); +#include "intrinsics_list.h" +INTRINSICS_LIST(OPTIMIZING_INTRINSICS) +#undef INTRINSICS_LIST + } // Compile: // 1) Compile all classes and methods enabled for compilation. May fall back to dex-to-dex // compilation. @@ -535,7 +565,7 @@ static optimizer::DexToDexCompilationLevel GetDexToDexCompilationLevel( ScopedObjectAccess soa(self); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); return GetDexToDexCompilationLevel(self, driver, class_loader, dex_file, class_def); } @@ -610,7 +640,7 @@ static void CompileMethod(Thread* self, ScopedObjectAccess soa(self); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader_handle(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(class_loader))); + soa.Decode<mirror::ClassLoader>(class_loader))); // TODO: Lookup annotation from DexFile directly without resolving method. ArtMethod* method = @@ -1626,7 +1656,7 @@ ArtField* CompilerDriver::ComputeInstanceFieldInfo(uint32_t field_idx, { StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader_handle( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(mUnit->GetClassLoader()))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(mUnit->GetClassLoader()))); resolved_field = ResolveField(soa, dex_cache, class_loader_handle, mUnit, field_idx, false); referrer_class = resolved_field != nullptr ? ResolveCompilingMethodsClass(soa, dex_cache, class_loader_handle, mUnit) : nullptr; @@ -1970,7 +2000,7 @@ class ResolveClassFieldsAndMethodsVisitor : public CompilationVisitor { ScopedObjectAccess soa(self); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->FindDexCache( soa.Self(), dex_file, false))); // Resolve the class. @@ -2067,7 +2097,7 @@ class ResolveTypeVisitor : public CompilationVisitor { const DexFile& dex_file = *manager_->GetDexFile(); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(manager_->GetClassLoader()))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(manager_->GetClassLoader()))); Handle<mirror::DexCache> dex_cache(hs.NewHandle(class_linker->RegisterDexFile( dex_file, class_loader.Get()))); @@ -2166,7 +2196,7 @@ class VerifyClassVisitor : public CompilationVisitor { jobject jclass_loader = manager_->GetClassLoader(); StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> klass( hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader))); if (klass.Get() == nullptr) { @@ -2254,7 +2284,7 @@ class SetVerifiedClassVisitor : public CompilationVisitor { jobject jclass_loader = manager_->GetClassLoader(); StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> klass( hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader))); // Class might have failed resolution. Then don't set it to verified. @@ -2316,7 +2346,7 @@ class InitializeClassVisitor : public CompilationVisitor { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> klass( hs.NewHandle(manager_->GetClassLinker()->FindClass(soa.Self(), descriptor, class_loader))); @@ -2551,7 +2581,7 @@ class CompileClassVisitor : public CompilationVisitor { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> klass( hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor, class_loader))); Handle<mirror::DexCache> dex_cache; diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 41f0d36c79..52a04cc46b 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -57,7 +57,6 @@ class CompiledClass; class CompiledMethod; class CompilerOptions; class DexCompilationUnit; -class DexFileToMethodInlinerMap; struct InlineIGetIPutData; class InstructionSetFeatures; class ParallelCompilationManager; @@ -88,7 +87,6 @@ class CompilerDriver { // classes. CompilerDriver(const CompilerOptions* compiler_options, VerificationResults* verification_results, - DexFileToMethodInlinerMap* method_inliner_map, Compiler::Kind compiler_kind, InstructionSet instruction_set, const InstructionSetFeatures* instruction_set_features, @@ -133,10 +131,6 @@ class CompilerDriver { return verification_results_; } - DexFileToMethodInlinerMap* GetMethodInlinerMap() const { - return method_inliner_map_; - } - InstructionSet GetInstructionSet() const { return instruction_set_; } @@ -603,7 +597,6 @@ class CompilerDriver { const CompilerOptions* const compiler_options_; VerificationResults* const verification_results_; - DexFileToMethodInlinerMap* const method_inliner_map_; std::unique_ptr<Compiler> compiler_; Compiler::Kind compiler_kind_; diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc index b9a5a781da..96f17accad 100644 --- a/compiler/driver/compiler_driver_test.cc +++ b/compiler/driver/compiler_driver_test.cc @@ -32,7 +32,7 @@ #include "mirror/object-inl.h" #include "handle_scope-inl.h" #include "jit/offline_profiling_info.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -83,7 +83,7 @@ class CompilerDriverTest : public CommonCompilerTest { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); mirror::Class* c = class_linker->FindClass(soa.Self(), descriptor, loader); CHECK(c != nullptr); const auto pointer_size = class_linker->GetImagePointerSize(); diff --git a/compiler/elf_writer.cc b/compiler/elf_writer.cc index ca0869a839..0c0609009d 100644 --- a/compiler/elf_writer.cc +++ b/compiler/elf_writer.cc @@ -26,7 +26,7 @@ #include "invoke_type.h" #include "mirror/object-inl.h" #include "oat.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/compiler/exception_test.cc b/compiler/exception_test.cc index 86f91c5ac4..f9e5cb9cb7 100644 --- a/compiler/exception_test.cc +++ b/compiler/exception_test.cc @@ -31,7 +31,7 @@ #include "oat_quick_method_header.h" #include "optimizing/stack_map_stream.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "handle_scope-inl.h" #include "thread.h" @@ -45,7 +45,7 @@ class ExceptionTest : public CommonRuntimeTest { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("ExceptionHandle")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("ExceptionHandle")))); my_klass_ = class_linker_->FindClass(soa.Self(), "LExceptionHandle;", class_loader); ASSERT_TRUE(my_klass_ != nullptr); Handle<mirror::Class> klass(hs.NewHandle(my_klass_)); @@ -219,7 +219,7 @@ TEST_F(ExceptionTest, StackTraceElement) { ASSERT_TRUE(internal != nullptr); jobjectArray ste_array = Thread::InternalStackTraceToStackTraceElementArray(soa, internal); ASSERT_TRUE(ste_array != nullptr); - auto* trace_array = soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(ste_array); + auto trace_array = soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>>(ste_array); ASSERT_TRUE(trace_array != nullptr); ASSERT_TRUE(trace_array->Get(0) != nullptr); diff --git a/compiler/image_test.cc b/compiler/image_test.cc index ea4b7ee40e..4689c9d300 100644 --- a/compiler/image_test.cc +++ b/compiler/image_test.cc @@ -33,7 +33,7 @@ #include "lock_word.h" #include "mirror/object-inl.h" #include "oat_writer.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "signal_catcher.h" #include "utils.h" diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc index 6b5758bc8f..41bda60a60 100644 --- a/compiler/image_writer.cc +++ b/compiler/image_writer.cc @@ -63,7 +63,7 @@ #include "oat_file.h" #include "oat_file_manager.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "handle_scope-inl.h" #include "utils/dex_cache_arrays_layout-inl.h" diff --git a/compiler/intrinsics_enum.h b/compiler/intrinsics_enum.h new file mode 100644 index 0000000000..55281812e4 --- /dev/null +++ b/compiler/intrinsics_enum.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_INTRINSICS_ENUM_H_ +#define ART_COMPILER_INTRINSICS_ENUM_H_ + +namespace art { + +enum class Intrinsics { +#define OPTIMIZING_INTRINSICS(Name, ...) \ + k ## Name, +#include "intrinsics_list.h" + kNone, + INTRINSICS_LIST(OPTIMIZING_INTRINSICS) +#undef INTRINSICS_LIST +#undef OPTIMIZING_INTRINSICS +}; +std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic); + +} // namespace art + +#endif // ART_COMPILER_INTRINSICS_ENUM_H_ diff --git a/compiler/intrinsics_list.h b/compiler/intrinsics_list.h new file mode 100644 index 0000000000..5877f57b74 --- /dev/null +++ b/compiler/intrinsics_list.h @@ -0,0 +1,147 @@ +/* + * Copyright (C, "", "", "") 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License", "", "", ""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_INTRINSICS_LIST_H_ +#define ART_COMPILER_INTRINSICS_LIST_H_ + +// All intrinsics supported by ART. Format is name, then whether it is expected +// to be a HInvokeStaticOrDirect node (compared to HInvokeVirtual), then whether it requires an +// environment, may have side effects, or may throw exceptions. + +// Note: adding a new intrinsic requires an art image version change, +// as the modifiers flag for some ArtMethods will need to be changed. + +#define INTRINSICS_LIST(V) \ + V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "doubleToRawLongBits", "(D)J") \ + V(DoubleDoubleToLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "doubleToLongBits", "(D)J") \ + V(DoubleIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "isInfinite", "(D)Z") \ + V(DoubleIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "isNaN", "(D)Z") \ + V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "longBitsToDouble", "(J)D") \ + V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "floatToRawIntBits", "(F)I") \ + V(FloatFloatToIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "floatToIntBits", "(F)I") \ + V(FloatIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "isInfinite", "(F)Z") \ + V(FloatIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "isNaN", "(F)Z") \ + V(FloatIntBitsToFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "intBitsToFloat", "(I)F") \ + V(IntegerReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "reverse", "(I)I") \ + V(IntegerReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "reverseBytes", "(I)I") \ + V(IntegerBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "bitCount", "(I)I") \ + V(IntegerCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "compare", "(II)I") \ + V(IntegerHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "highestOneBit", "(I)I") \ + V(IntegerLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "lowestOneBit", "(I)I") \ + V(IntegerNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "numberOfLeadingZeros", "(I)I") \ + V(IntegerNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "numberOfTrailingZeros", "(I)I") \ + V(IntegerRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "rotateRight", "(II)I") \ + V(IntegerRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "rotateLeft", "(II)I") \ + V(IntegerSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "signum", "(I)I") \ + V(LongReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "reverse", "(J)J") \ + V(LongReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "reverseBytes", "(J)J") \ + V(LongBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "bitCount", "(J)I") \ + V(LongCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "compare", "(JJ)I") \ + V(LongHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "highestOneBit", "(J)J") \ + V(LongLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "lowestOneBit", "(J)J") \ + V(LongNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "numberOfLeadingZeros", "(J)I") \ + V(LongNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "numberOfTrailingZeros", "(J)I") \ + V(LongRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "rotateRight", "(JI)J") \ + V(LongRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "rotateLeft", "(JI)J") \ + V(LongSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "signum", "(J)I") \ + V(ShortReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Short;", "reverseBytes", "(S)S") \ + V(MathAbsDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(D)D") \ + V(MathAbsFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(F)F") \ + V(MathAbsLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(J)J") \ + V(MathAbsInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(I)I") \ + V(MathMinDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(DD)D") \ + V(MathMinFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(FF)F") \ + V(MathMinLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(JJ)J") \ + V(MathMinIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(II)I") \ + V(MathMaxDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(DD)D") \ + V(MathMaxFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(FF)F") \ + V(MathMaxLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(JJ)J") \ + V(MathMaxIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(II)I") \ + V(MathCos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "cos", "(D)D") \ + V(MathSin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "sin", "(D)D") \ + V(MathAcos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "acos", "(D)D") \ + V(MathAsin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "asin", "(D)D") \ + V(MathAtan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "atan", "(D)D") \ + V(MathAtan2, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "atan2", "(DD)D") \ + V(MathCbrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "cbrt", "(D)D") \ + V(MathCosh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "cosh", "(D)D") \ + V(MathExp, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "exp", "(D)D") \ + V(MathExpm1, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "expm1", "(D)D") \ + V(MathHypot, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "hypot", "(DD)D") \ + V(MathLog, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "log", "(D)D") \ + V(MathLog10, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "log10", "(D)D") \ + V(MathNextAfter, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "nextAfter", "(DD)D") \ + V(MathSinh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "sinh", "(D)D") \ + V(MathTan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "tan", "(D)D") \ + V(MathTanh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "tanh", "(D)D") \ + V(MathSqrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "sqrt", "(D)D") \ + V(MathCeil, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "ceil", "(D)D") \ + V(MathFloor, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "floor", "(D)D") \ + V(MathRint, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "rint", "(D)D") \ + V(MathRoundDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "round", "(D)J") \ + V(MathRoundFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "round", "(F)I") \ + V(SystemArrayCopyChar, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/System;", "arraycopy", "([CI[CII)V") \ + V(SystemArrayCopy, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/System;", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V") \ + V(ThreadCurrentThread, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Thread;", "currentThread", "()Ljava/lang/Thread;") \ + V(MemoryPeekByte, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekByte", "(J)B") \ + V(MemoryPeekIntNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekIntNative", "(J)I") \ + V(MemoryPeekLongNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekLongNative", "(J)J") \ + V(MemoryPeekShortNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekShortNative", "(J)S") \ + V(MemoryPokeByte, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeByte", "(JB)V") \ + V(MemoryPokeIntNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeIntNative", "(JI)V") \ + V(MemoryPokeLongNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeLongNative", "(JJ)V") \ + V(MemoryPokeShortNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeShortNative", "(JS)V") \ + V(StringCharAt, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "charAt", "(I)C") \ + V(StringCompareTo, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "compareTo", "(Ljava/lang/String;)I") \ + V(StringEquals, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "equals", "(Ljava/lang/Object;)Z") \ + V(StringGetCharsNoCheck, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "getCharsNoCheck", "(II[CI)V") \ + V(StringIndexOf, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "indexOf", "(I)I") \ + V(StringIndexOfAfter, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "indexOf", "(II)I") \ + V(StringIsEmpty, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow, "Ljava/lang/String;", "isEmpty", "()Z") \ + V(StringLength, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow, "Ljava/lang/String;", "length", "()I") \ + V(StringNewStringFromBytes, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/StringFactory;", "newStringFromBytes", "([BIII)Ljava/lang/String;") \ + V(StringNewStringFromChars, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/StringFactory;", "newStringFromChars", "(II[C)Ljava/lang/String;") \ + V(StringNewStringFromString, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/StringFactory;", "newStringFromString", "(Ljava/lang/String;)Ljava/lang/String;") \ + V(UnsafeCASInt, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "compareAndSwapInt", "(Ljava/lang/Object;JII)Z") \ + V(UnsafeCASLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z") \ + V(UnsafeCASObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \ + V(UnsafeGet, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getInt", "(Ljava/lang/Object;J)I") \ + V(UnsafeGetVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getIntVolatile", "(Ljava/lang/Object;J)I") \ + V(UnsafeGetObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;") \ + V(UnsafeGetObjectVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;") \ + V(UnsafeGetLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getLong", "(Ljava/lang/Object;J)J") \ + V(UnsafeGetLongVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getLongVolatile", "(Ljava/lang/Object;J)J") \ + V(UnsafePut, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putInt", "(Ljava/lang/Object;JI)V") \ + V(UnsafePutOrdered, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedInt", "(Ljava/lang/Object;JI)V") \ + V(UnsafePutVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putIntVolatile", "(Ljava/lang/Object;JI)V") \ + V(UnsafePutObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V") \ + V(UnsafePutObjectOrdered, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V") \ + V(UnsafePutObjectVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V") \ + V(UnsafePutLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putLong", "(Ljava/lang/Object;JJ)V") \ + V(UnsafePutLongOrdered, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedLong", "(Ljava/lang/Object;JJ)V") \ + V(UnsafePutLongVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putLongVolatile", "(Ljava/lang/Object;JJ)V") \ + V(UnsafeGetAndAddInt, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndAddInt", "(Ljava/lang/Object;JI)I") \ + V(UnsafeGetAndAddLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndAddLong", "(Ljava/lang/Object;JJ)J") \ + V(UnsafeGetAndSetInt, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetInt", "(Ljava/lang/Object;JI)I") \ + V(UnsafeGetAndSetLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetLong", "(Ljava/lang/Object;JJ)J") \ + V(UnsafeGetAndSetObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetObject", "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;") \ + V(UnsafeLoadFence, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "loadFence", "()V") \ + V(UnsafeStoreFence, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "storeFence", "()V") \ + V(UnsafeFullFence, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "fullFence", "()V") \ + V(ReferenceGetReferent, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/ref/Reference;", "getReferent", "()Ljava/lang/Object;") + +#endif // ART_COMPILER_INTRINSICS_LIST_H_ +#undef ART_COMPILER_INTRINSICS_LIST_H_ // #define is only for lint. diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index 7246acebd2..4f8690530b 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -150,11 +150,9 @@ JitCompiler::JitCompiler() { instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines()); } cumulative_logger_.reset(new CumulativeLogger("jit times")); - method_inliner_map_.reset(new DexFileToMethodInlinerMap); compiler_driver_.reset(new CompilerDriver( compiler_options_.get(), /* verification_results */ nullptr, - method_inliner_map_.get(), Compiler::kOptimizing, instruction_set, instruction_set_features_.get(), diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h index 18e3155040..ea2747c085 100644 --- a/compiler/jit/jit_compiler.h +++ b/compiler/jit/jit_compiler.h @@ -19,7 +19,6 @@ #include "base/mutex.h" #include "compiled_method.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -49,7 +48,6 @@ class JitCompiler { private: std::unique_ptr<CompilerOptions> compiler_options_; std::unique_ptr<CumulativeLogger> cumulative_logger_; - std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_; std::unique_ptr<CompilerDriver> compiler_driver_; std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; std::unique_ptr<File> perf_file_; diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc index 14301884dd..19d55a3845 100644 --- a/compiler/jni/jni_compiler_test.cc +++ b/compiler/jni/jni_compiler_test.cc @@ -36,7 +36,7 @@ #include "nativeloader/native_loader.h" #include "runtime.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_bar(JNIEnv*, jobject, jint count) { @@ -238,7 +238,7 @@ class JniCompilerTest : public CommonCompilerTest { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); // Compile the native method before starting the runtime mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader); const auto pointer_size = class_linker_->GetImagePointerSize(); @@ -1140,8 +1140,8 @@ jint Java_MyClassNatives_nativeUpCall(JNIEnv* env, jobject thisObj, jint i) { // Build stack trace jobject internal = Thread::Current()->CreateInternalStackTrace<false>(soa); jobjectArray ste_array = Thread::InternalStackTraceToStackTraceElementArray(soa, internal); - mirror::ObjectArray<mirror::StackTraceElement>* trace_array = - soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(ste_array); + ObjPtr<mirror::ObjectArray<mirror::StackTraceElement>> trace_array = + soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>>(ste_array); EXPECT_TRUE(trace_array != nullptr); EXPECT_EQ(11, trace_array->GetLength()); @@ -1205,7 +1205,7 @@ jint local_ref_test(JNIEnv* env, jobject thisObj, jint x) { // Add 10 local references ScopedObjectAccess soa(env); for (int i = 0; i < 10; i++) { - soa.AddLocalReference<jobject>(soa.Decode<mirror::Object*>(thisObj)); + soa.AddLocalReference<jobject>(soa.Decode<mirror::Object>(thisObj)); } return x+1; } @@ -1283,7 +1283,7 @@ jarray Java_MyClassNatives_GetSinkProperties(JNIEnv*, jobject thisObj, jstring s Thread* self = Thread::Current(); ScopedObjectAccess soa(self); - EXPECT_TRUE(self->HoldsLock(soa.Decode<mirror::Object*>(thisObj))); + EXPECT_TRUE(self->HoldsLock(soa.Decode<mirror::Object>(thisObj).Decode())); return nullptr; } diff --git a/compiler/linker/relative_patcher_test.h b/compiler/linker/relative_patcher_test.h index 304b31ca84..62b3a0a167 100644 --- a/compiler/linker/relative_patcher_test.h +++ b/compiler/linker/relative_patcher_test.h @@ -22,7 +22,6 @@ #include "base/array_ref.h" #include "base/macros.h" #include "compiled_method.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -43,10 +42,8 @@ class RelativePatcherTest : public testing::Test { RelativePatcherTest(InstructionSet instruction_set, const std::string& variant) : compiler_options_(), verification_results_(&compiler_options_), - inliner_map_(), driver_(&compiler_options_, &verification_results_, - &inliner_map_, Compiler::kQuick, instruction_set, /* instruction_set_features*/ nullptr, @@ -269,7 +266,6 @@ class RelativePatcherTest : public testing::Test { CompilerOptions compiler_options_; VerificationResults verification_results_; - DexFileToMethodInlinerMap inliner_map_; CompilerDriver driver_; // Needed for constructing CompiledMethod. std::string error_msg_; InstructionSet instruction_set_; diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index 24d102d4c0..e8bc67d967 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -23,7 +23,6 @@ #include "compiled_method.h" #include "compiler.h" #include "debug/method_debug_info.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/quick_compiler_callbacks.h" #include "dex/verification_results.h" #include "driver/compiler_driver.h" @@ -38,7 +37,7 @@ #include "mirror/object_array-inl.h" #include "oat_file-inl.h" #include "oat_writer.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "utils/test_dex_file_builder.h" namespace art { @@ -100,15 +99,12 @@ class OatTest : public CommonCompilerTest { compiler_options_->ParseCompilerOption(option, Usage); } verification_results_.reset(new VerificationResults(compiler_options_.get())); - method_inliner_map_.reset(new DexFileToMethodInlinerMap); callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(), - method_inliner_map_.get(), CompilerCallbacks::CallbackMode::kCompileApp)); Runtime::Current()->SetCompilerCallbacks(callbacks_.get()); timer_.reset(new CumulativeLogger("Compilation times")); compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - method_inliner_map_.get(), compiler_kind, insn_set, insn_features_.get(), @@ -501,7 +497,8 @@ TEST_F(OatTest, EmptyTextSection) { ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); for (const DexFile* dex_file : dex_files) { ScopedObjectAccess soa(Thread::Current()); - class_linker->RegisterDexFile(*dex_file, soa.Decode<mirror::ClassLoader*>(class_loader)); + class_linker->RegisterDexFile(*dex_file, + soa.Decode<mirror::ClassLoader>(class_loader).Decode()); } compiler_driver_->SetDexFilesForOatFile(dex_files); compiler_driver_->CompileAll(class_loader, dex_files, &timings); diff --git a/compiler/oat_writer.cc b/compiler/oat_writer.cc index c840a9e64a..54ec7c1edb 100644 --- a/compiler/oat_writer.cc +++ b/compiler/oat_writer.cc @@ -50,7 +50,7 @@ #include "oat_quick_method_header.h" #include "os.h" #include "safe_map.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "type_lookup_table.h" #include "utils/dex_cache_arrays_layout-inl.h" #include "vdex_file.h" diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index f21dc0e7e4..af2fe9cb1f 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -41,7 +41,7 @@ #include "sharpening.h" #include "ssa_builder.h" #include "ssa_phi_elimination.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { @@ -1321,7 +1321,7 @@ size_t HInliner::RunOptimizations(HGraph* callee_graph, HConstantFolding fold(callee_graph); HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_); InstructionSimplifier simplify(callee_graph, stats_); - IntrinsicsRecognizer intrinsics(callee_graph, compiler_driver_, stats_); + IntrinsicsRecognizer intrinsics(callee_graph, stats_); HOptimization* optimizations[] = { &intrinsics, diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 3b08d9f989..f7d67db5b2 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -22,7 +22,7 @@ #include "dex_instruction-inl.h" #include "driver/compiler_options.h" #include "imtable-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -675,7 +675,7 @@ ArtMethod* HInstructionBuilder::ResolveMethod(uint16_t method_idx, InvokeType in ClassLinker* class_linker = dex_compilation_unit_->GetClassLinker(); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); Handle<mirror::Class> compiling_class(hs.NewHandle(GetCompilingClass())); // We fetch the referenced class eagerly (that is, the class pointed by in the MethodId // at method_idx), as `CanAccessResolvedMethod` expects it be be in the dex cache. @@ -1284,7 +1284,7 @@ static mirror::Class* GetClassFrom(CompilerDriver* driver, ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(compilation_unit.GetClassLoader()))); + soa.Decode<mirror::ClassLoader>(compilation_unit.GetClassLoader()))); Handle<mirror::DexCache> dex_cache = compilation_unit.GetDexCache(); return driver->ResolveCompilingMethodsClass(soa, dex_cache, class_loader, &compilation_unit); @@ -1303,7 +1303,7 @@ bool HInstructionBuilder::IsOutermostCompilingClass(uint16_t type_index) const { StackHandleScope<3> hs(soa.Self()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); Handle<mirror::Class> cls(hs.NewHandle(compiler_driver_->ResolveClass( soa, dex_cache, class_loader, type_index, dex_compilation_unit_))); Handle<mirror::Class> outer_class(hs.NewHandle(GetOutermostCompilingClass())); @@ -1344,7 +1344,7 @@ bool HInstructionBuilder::BuildStaticFieldAccess(const Instruction& instruction, StackHandleScope<3> hs(soa.Self()); Handle<mirror::DexCache> dex_cache = dex_compilation_unit_->GetDexCache(); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(dex_compilation_unit_->GetClassLoader()))); + soa.Decode<mirror::ClassLoader>(dex_compilation_unit_->GetClassLoader()))); ArtField* resolved_field = compiler_driver_->ResolveField( soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true); diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index ff829af4c2..3bb1c1dc21 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -18,7 +18,7 @@ #include "intrinsics.h" #include "mirror/class-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 4d4bbcf616..412ccfcf4f 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -18,14 +18,11 @@ #include "art_method.h" #include "class_linker.h" -#include "dex/quick/dex_file_method_inliner.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_driver.h" #include "invoke_type.h" #include "mirror/dex_cache-inl.h" #include "nodes.h" -#include "quick/inline_method_analyser.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" @@ -36,7 +33,7 @@ static inline InvokeType GetIntrinsicInvokeType(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kInterface; // Non-sensical for intrinsic. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return IsStatic; #include "intrinsics_list.h" @@ -52,7 +49,7 @@ static inline IntrinsicNeedsEnvironmentOrCache NeedsEnvironmentOrCache(Intrinsic switch (i) { case Intrinsics::kNone: return kNeedsEnvironmentOrCache; // Non-sensical for intrinsic. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return NeedsEnvironmentOrCache; #include "intrinsics_list.h" @@ -68,7 +65,7 @@ static inline IntrinsicSideEffects GetSideEffects(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kAllSideEffects; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return SideEffects; #include "intrinsics_list.h" @@ -84,7 +81,7 @@ static inline IntrinsicExceptions GetExceptions(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kCanThrow; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return Exceptions; #include "intrinsics_list.h" @@ -95,430 +92,7 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS) return kCanThrow; } -static Primitive::Type GetType(uint64_t data, bool is_op_size) { - if (is_op_size) { - switch (static_cast<OpSize>(data)) { - case kSignedByte: - return Primitive::kPrimByte; - case kSignedHalf: - return Primitive::kPrimShort; - case k32: - return Primitive::kPrimInt; - case k64: - return Primitive::kPrimLong; - default: - LOG(FATAL) << "Unknown/unsupported op size " << data; - UNREACHABLE(); - } - } else { - if ((data & kIntrinsicFlagIsLong) != 0) { - return Primitive::kPrimLong; - } - if ((data & kIntrinsicFlagIsObject) != 0) { - return Primitive::kPrimNot; - } - return Primitive::kPrimInt; - } -} - -static Intrinsics GetIntrinsic(InlineMethod method) { - switch (method.opcode) { - // Floating-point conversions. - case kIntrinsicDoubleCvt: - return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? - Intrinsics::kDoubleDoubleToRawLongBits : Intrinsics::kDoubleLongBitsToDouble; - case kIntrinsicFloatCvt: - return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? - Intrinsics::kFloatFloatToRawIntBits : Intrinsics::kFloatIntBitsToFloat; - case kIntrinsicFloat2Int: - return Intrinsics::kFloatFloatToIntBits; - case kIntrinsicDouble2Long: - return Intrinsics::kDoubleDoubleToLongBits; - - // Floating-point tests. - case kIntrinsicFloatIsInfinite: - return Intrinsics::kFloatIsInfinite; - case kIntrinsicDoubleIsInfinite: - return Intrinsics::kDoubleIsInfinite; - case kIntrinsicFloatIsNaN: - return Intrinsics::kFloatIsNaN; - case kIntrinsicDoubleIsNaN: - return Intrinsics::kDoubleIsNaN; - - // Bit manipulations. - case kIntrinsicReverseBits: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerReverse; - case Primitive::kPrimLong: - return Intrinsics::kLongReverse; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicReverseBytes: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimShort: - return Intrinsics::kShortReverseBytes; - case Primitive::kPrimInt: - return Intrinsics::kIntegerReverseBytes; - case Primitive::kPrimLong: - return Intrinsics::kLongReverseBytes; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicRotateRight: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerRotateRight; - case Primitive::kPrimLong: - return Intrinsics::kLongRotateRight; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicRotateLeft: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerRotateLeft; - case Primitive::kPrimLong: - return Intrinsics::kLongRotateLeft; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // Misc data processing. - case kIntrinsicBitCount: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerBitCount; - case Primitive::kPrimLong: - return Intrinsics::kLongBitCount; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicCompare: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerCompare; - case Primitive::kPrimLong: - return Intrinsics::kLongCompare; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicHighestOneBit: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerHighestOneBit; - case Primitive::kPrimLong: - return Intrinsics::kLongHighestOneBit; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicLowestOneBit: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerLowestOneBit; - case Primitive::kPrimLong: - return Intrinsics::kLongLowestOneBit; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicNumberOfLeadingZeros: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerNumberOfLeadingZeros; - case Primitive::kPrimLong: - return Intrinsics::kLongNumberOfLeadingZeros; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicNumberOfTrailingZeros: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerNumberOfTrailingZeros; - case Primitive::kPrimLong: - return Intrinsics::kLongNumberOfTrailingZeros; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicSignum: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerSignum; - case Primitive::kPrimLong: - return Intrinsics::kLongSignum; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // Abs. - case kIntrinsicAbsDouble: - return Intrinsics::kMathAbsDouble; - case kIntrinsicAbsFloat: - return Intrinsics::kMathAbsFloat; - case kIntrinsicAbsInt: - return Intrinsics::kMathAbsInt; - case kIntrinsicAbsLong: - return Intrinsics::kMathAbsLong; - - // Min/max. - case kIntrinsicMinMaxDouble: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxDoubleDouble : Intrinsics::kMathMinDoubleDouble; - case kIntrinsicMinMaxFloat: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxFloatFloat : Intrinsics::kMathMinFloatFloat; - case kIntrinsicMinMaxInt: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxIntInt : Intrinsics::kMathMinIntInt; - case kIntrinsicMinMaxLong: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxLongLong : Intrinsics::kMathMinLongLong; - - // More math builtins. - case kIntrinsicCos: - return Intrinsics::kMathCos; - case kIntrinsicSin: - return Intrinsics::kMathSin; - case kIntrinsicAcos: - return Intrinsics::kMathAcos; - case kIntrinsicAsin: - return Intrinsics::kMathAsin; - case kIntrinsicAtan: - return Intrinsics::kMathAtan; - case kIntrinsicAtan2: - return Intrinsics::kMathAtan2; - case kIntrinsicCbrt: - return Intrinsics::kMathCbrt; - case kIntrinsicCosh: - return Intrinsics::kMathCosh; - case kIntrinsicExp: - return Intrinsics::kMathExp; - case kIntrinsicExpm1: - return Intrinsics::kMathExpm1; - case kIntrinsicHypot: - return Intrinsics::kMathHypot; - case kIntrinsicLog: - return Intrinsics::kMathLog; - case kIntrinsicLog10: - return Intrinsics::kMathLog10; - case kIntrinsicNextAfter: - return Intrinsics::kMathNextAfter; - case kIntrinsicSinh: - return Intrinsics::kMathSinh; - case kIntrinsicTan: - return Intrinsics::kMathTan; - case kIntrinsicTanh: - return Intrinsics::kMathTanh; - - // Misc math. - case kIntrinsicSqrt: - return Intrinsics::kMathSqrt; - case kIntrinsicCeil: - return Intrinsics::kMathCeil; - case kIntrinsicFloor: - return Intrinsics::kMathFloor; - case kIntrinsicRint: - return Intrinsics::kMathRint; - case kIntrinsicRoundDouble: - return Intrinsics::kMathRoundDouble; - case kIntrinsicRoundFloat: - return Intrinsics::kMathRoundFloat; - - // System.arraycopy. - case kIntrinsicSystemArrayCopyCharArray: - return Intrinsics::kSystemArrayCopyChar; - - case kIntrinsicSystemArrayCopy: - return Intrinsics::kSystemArrayCopy; - - // Thread.currentThread. - case kIntrinsicCurrentThread: - return Intrinsics::kThreadCurrentThread; - - // Memory.peek. - case kIntrinsicPeek: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimByte: - return Intrinsics::kMemoryPeekByte; - case Primitive::kPrimShort: - return Intrinsics::kMemoryPeekShortNative; - case Primitive::kPrimInt: - return Intrinsics::kMemoryPeekIntNative; - case Primitive::kPrimLong: - return Intrinsics::kMemoryPeekLongNative; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // Memory.poke. - case kIntrinsicPoke: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimByte: - return Intrinsics::kMemoryPokeByte; - case Primitive::kPrimShort: - return Intrinsics::kMemoryPokeShortNative; - case Primitive::kPrimInt: - return Intrinsics::kMemoryPokeIntNative; - case Primitive::kPrimLong: - return Intrinsics::kMemoryPokeLongNative; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // String. - case kIntrinsicCharAt: - return Intrinsics::kStringCharAt; - case kIntrinsicCompareTo: - return Intrinsics::kStringCompareTo; - case kIntrinsicEquals: - return Intrinsics::kStringEquals; - case kIntrinsicGetCharsNoCheck: - return Intrinsics::kStringGetCharsNoCheck; - case kIntrinsicIsEmptyOrLength: - return ((method.d.data & kIntrinsicFlagIsEmpty) == 0) ? - Intrinsics::kStringLength : Intrinsics::kStringIsEmpty; - case kIntrinsicIndexOf: - return ((method.d.data & kIntrinsicFlagBase0) == 0) ? - Intrinsics::kStringIndexOfAfter : Intrinsics::kStringIndexOf; - case kIntrinsicNewStringFromBytes: - return Intrinsics::kStringNewStringFromBytes; - case kIntrinsicNewStringFromChars: - return Intrinsics::kStringNewStringFromChars; - case kIntrinsicNewStringFromString: - return Intrinsics::kStringNewStringFromString; - - case kIntrinsicCas: - switch (GetType(method.d.data, false)) { - case Primitive::kPrimNot: - return Intrinsics::kUnsafeCASObject; - case Primitive::kPrimInt: - return Intrinsics::kUnsafeCASInt; - case Primitive::kPrimLong: - return Intrinsics::kUnsafeCASLong; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicUnsafeGet: { - const bool is_volatile = (method.d.data & kIntrinsicFlagIsVolatile); - switch (GetType(method.d.data, false)) { - case Primitive::kPrimInt: - return is_volatile ? Intrinsics::kUnsafeGetVolatile : Intrinsics::kUnsafeGet; - case Primitive::kPrimLong: - return is_volatile ? Intrinsics::kUnsafeGetLongVolatile : Intrinsics::kUnsafeGetLong; - case Primitive::kPrimNot: - return is_volatile ? Intrinsics::kUnsafeGetObjectVolatile : Intrinsics::kUnsafeGetObject; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - } - case kIntrinsicUnsafePut: { - enum Sync { kNoSync, kVolatile, kOrdered }; - const Sync sync = - ((method.d.data & kIntrinsicFlagIsVolatile) != 0) ? kVolatile : - ((method.d.data & kIntrinsicFlagIsOrdered) != 0) ? kOrdered : - kNoSync; - switch (GetType(method.d.data, false)) { - case Primitive::kPrimInt: - switch (sync) { - case kNoSync: - return Intrinsics::kUnsafePut; - case kVolatile: - return Intrinsics::kUnsafePutVolatile; - case kOrdered: - return Intrinsics::kUnsafePutOrdered; - } - break; - case Primitive::kPrimLong: - switch (sync) { - case kNoSync: - return Intrinsics::kUnsafePutLong; - case kVolatile: - return Intrinsics::kUnsafePutLongVolatile; - case kOrdered: - return Intrinsics::kUnsafePutLongOrdered; - } - break; - case Primitive::kPrimNot: - switch (sync) { - case kNoSync: - return Intrinsics::kUnsafePutObject; - case kVolatile: - return Intrinsics::kUnsafePutObjectVolatile; - case kOrdered: - return Intrinsics::kUnsafePutObjectOrdered; - } - break; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - break; - } - - // 1.8. - case kIntrinsicUnsafeGetAndAddInt: - return Intrinsics::kUnsafeGetAndAddInt; - case kIntrinsicUnsafeGetAndAddLong: - return Intrinsics::kUnsafeGetAndAddLong; - case kIntrinsicUnsafeGetAndSetInt: - return Intrinsics::kUnsafeGetAndSetInt; - case kIntrinsicUnsafeGetAndSetLong: - return Intrinsics::kUnsafeGetAndSetLong; - case kIntrinsicUnsafeGetAndSetObject: - return Intrinsics::kUnsafeGetAndSetObject; - case kIntrinsicUnsafeLoadFence: - return Intrinsics::kUnsafeLoadFence; - case kIntrinsicUnsafeStoreFence: - return Intrinsics::kUnsafeStoreFence; - case kIntrinsicUnsafeFullFence: - return Intrinsics::kUnsafeFullFence; - - // Virtual cases. - - case kIntrinsicReferenceGetReferent: - return Intrinsics::kReferenceGetReferent; - - // Quick inliner cases. Remove after refactoring. They are here so that we can use the - // compiler to warn on missing cases. - - case kInlineOpNop: - case kInlineOpReturnArg: - case kInlineOpNonWideConst: - case kInlineOpIGet: - case kInlineOpIPut: - case kInlineOpConstructor: - return Intrinsics::kNone; - - // String init cases, not intrinsics. - - case kInlineStringInit: - return Intrinsics::kNone; - - // No default case to make the compiler warn on missing cases. - } - return Intrinsics::kNone; -} - -static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile& dex_file) { - // The DexFileMethodInliner should have checked whether the methods are agreeing with - // what we expect, i.e., static methods are called as such. Add another check here for - // our expectations: - // +static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke) { // Whenever the intrinsic is marked as static, report an error if we find an InvokeVirtual. // // Whenever the intrinsic is marked as direct and we find an InvokeVirtual, a devirtualization @@ -542,13 +116,9 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile return true; } if (invoke_type == kVirtual) { - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + ArtMethod* art_method = invoke->GetResolvedMethod(); ScopedObjectAccess soa(Thread::Current()); - ArtMethod* art_method = - class_linker->FindDexCache(soa.Self(), dex_file)->GetResolvedMethod( - invoke->GetDexMethodIndex(), class_linker->GetImagePointerSize()); - return art_method != nullptr && - (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal()); + return (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal()); } return false; @@ -561,8 +131,8 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile } } -// TODO: Refactor DexFileMethodInliner and have something nicer than InlineMethod. void IntrinsicsRecognizer::Run() { + ScopedObjectAccess soa(Thread::Current()); for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { HBasicBlock* block = it.Current(); for (HInstructionIterator inst_it(block->GetInstructions()); !inst_it.Done(); @@ -570,26 +140,20 @@ void IntrinsicsRecognizer::Run() { HInstruction* inst = inst_it.Current(); if (inst->IsInvoke()) { HInvoke* invoke = inst->AsInvoke(); - InlineMethod method; - const DexFile& dex_file = invoke->GetDexFile(); - DexFileMethodInliner* inliner = driver_->GetMethodInlinerMap()->GetMethodInliner(&dex_file); - DCHECK(inliner != nullptr); - if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) { - Intrinsics intrinsic = GetIntrinsic(method); - - if (intrinsic != Intrinsics::kNone) { - if (!CheckInvokeType(intrinsic, invoke, dex_file)) { - LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " - << intrinsic << " for " - << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()) - << invoke->DebugName(); - } else { - invoke->SetIntrinsic(intrinsic, - NeedsEnvironmentOrCache(intrinsic), - GetSideEffects(intrinsic), - GetExceptions(intrinsic)); - MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized); - } + ArtMethod* art_method = invoke->GetResolvedMethod(); + if (art_method != nullptr && art_method->IsIntrinsic()) { + Intrinsics intrinsic = static_cast<Intrinsics>(art_method->GetIntrinsic()); + if (!CheckInvokeType(intrinsic, invoke)) { + LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " + << intrinsic << " for " + << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()) + << invoke->DebugName(); + } else { + invoke->SetIntrinsic(intrinsic, + NeedsEnvironmentOrCache(intrinsic), + GetSideEffects(intrinsic), + GetExceptions(intrinsic)); + MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized); } } } @@ -602,7 +166,7 @@ std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) { case Intrinsics::kNone: os << "None"; break; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ os << # Name; \ break; diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h index 62f731d03f..1e73cf67df 100644 --- a/compiler/optimizing/intrinsics.h +++ b/compiler/optimizing/intrinsics.h @@ -34,17 +34,14 @@ static constexpr uint64_t kPositiveInfinityDouble = UINT64_C(0x7ff0000000000000) // Recognize intrinsics from HInvoke nodes. class IntrinsicsRecognizer : public HOptimization { public: - IntrinsicsRecognizer(HGraph* graph, CompilerDriver* driver, OptimizingCompilerStats* stats) - : HOptimization(graph, kIntrinsicsRecognizerPassName, stats), - driver_(driver) {} + IntrinsicsRecognizer(HGraph* graph, OptimizingCompilerStats* stats) + : HOptimization(graph, kIntrinsicsRecognizerPassName, stats) {} void Run() OVERRIDE; static constexpr const char* kIntrinsicsRecognizerPassName = "intrinsics_recognition"; private: - CompilerDriver* driver_; - DISALLOW_COPY_AND_ASSIGN(IntrinsicsRecognizer); }; @@ -58,7 +55,7 @@ class IntrinsicVisitor : public ValueObject { switch (invoke->GetIntrinsic()) { case Intrinsics::kNone: return; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, ...) \ case Intrinsics::k ## Name: \ Visit ## Name(invoke); \ return; @@ -73,7 +70,7 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS) // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, ...) \ virtual void Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) { \ } #include "intrinsics_list.h" diff --git a/compiler/optimizing/intrinsics_arm.h b/compiler/optimizing/intrinsics_arm.h index c671700615..7f20ea4b1f 100644 --- a/compiler/optimizing/intrinsics_arm.h +++ b/compiler/optimizing/intrinsics_arm.h @@ -37,7 +37,7 @@ class IntrinsicLocationsBuilderARM FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -64,7 +64,7 @@ class IntrinsicCodeGeneratorARM FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_arm64.h b/compiler/optimizing/intrinsics_arm64.h index 525153621b..28e41cb086 100644 --- a/compiler/optimizing/intrinsics_arm64.h +++ b/compiler/optimizing/intrinsics_arm64.h @@ -42,7 +42,7 @@ class IntrinsicLocationsBuilderARM64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -66,7 +66,7 @@ class IntrinsicCodeGeneratorARM64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_list.h b/compiler/optimizing/intrinsics_list.h deleted file mode 100644 index db60238fb4..0000000000 --- a/compiler/optimizing/intrinsics_list.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ -#define ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ - -// All intrinsics supported by the optimizing compiler. Format is name, then whether it is expected -// to be a HInvokeStaticOrDirect node (compared to HInvokeVirtual), then whether it requires an -// environment, may have side effects, or may throw exceptions. - -#define INTRINSICS_LIST(V) \ - V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleDoubleToLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatFloatToIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatIntBitsToFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(ShortReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathSin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAcos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAsin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAtan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAtan2, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCbrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCosh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathExp, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathExpm1, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathHypot, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathLog, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathLog10, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathNextAfter, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathSinh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathTan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathTanh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathSqrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCeil, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathFloor, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathRint, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathRoundDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathRoundFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(SystemArrayCopyChar, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(SystemArrayCopy, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(ThreadCurrentThread, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MemoryPeekByte, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPeekIntNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPeekLongNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPeekShortNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPokeByte, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(MemoryPokeIntNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(MemoryPokeLongNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(MemoryPokeShortNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(StringCharAt, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringCompareTo, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringEquals, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringGetCharsNoCheck, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringIndexOf, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringIndexOfAfter, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringIsEmpty, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow) \ - V(StringLength, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow) \ - V(StringNewStringFromBytes, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(StringNewStringFromChars, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(StringNewStringFromString, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeCASInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeCASLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeCASObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGet, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetObjectVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetLongVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePut, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutObjectOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutObjectVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutLongOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutLongVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndAddInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndAddLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndSetInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndSetLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndSetObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeLoadFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeStoreFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeFullFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(ReferenceGetReferent, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) - -#endif // ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ -#undef ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ // #define is only for lint. diff --git a/compiler/optimizing/intrinsics_mips.h b/compiler/optimizing/intrinsics_mips.h index 575a7d0a23..e134cb882e 100644 --- a/compiler/optimizing/intrinsics_mips.h +++ b/compiler/optimizing/intrinsics_mips.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderMIPS FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -60,7 +60,7 @@ class IntrinsicCodeGeneratorMIPS FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_mips64.h b/compiler/optimizing/intrinsics_mips64.h index 4137fbd1b6..5b95c26a21 100644 --- a/compiler/optimizing/intrinsics_mips64.h +++ b/compiler/optimizing/intrinsics_mips64.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderMIPS64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -60,7 +60,7 @@ class IntrinsicCodeGeneratorMIPS64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_x86.h b/compiler/optimizing/intrinsics_x86.h index 08bd197400..3743cb1371 100644 --- a/compiler/optimizing/intrinsics_x86.h +++ b/compiler/optimizing/intrinsics_x86.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderX86 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -61,7 +61,7 @@ class IntrinsicCodeGeneratorX86 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_x86_64.h b/compiler/optimizing/intrinsics_x86_64.h index 155ff6548b..97404aa568 100644 --- a/compiler/optimizing/intrinsics_x86_64.h +++ b/compiler/optimizing/intrinsics_x86_64.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderX86_64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -61,7 +61,7 @@ class IntrinsicCodeGeneratorX86_64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 9cfa89b7d0..ef9bf23a17 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -25,7 +25,7 @@ #include "base/stl_util.h" #include "intrinsics.h" #include "mirror/class-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 4dc4c20003..397abded27 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -32,6 +32,7 @@ #include "handle.h" #include "handle_scope.h" #include "invoke_type.h" +#include "intrinsics_enum.h" #include "locations.h" #include "method_reference.h" #include "mirror/class.h" @@ -3690,17 +3691,6 @@ class HNewInstance FINAL : public HExpression<2> { DISALLOW_COPY_AND_ASSIGN(HNewInstance); }; -enum class Intrinsics { -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ - k ## Name, -#include "intrinsics_list.h" - kNone, - INTRINSICS_LIST(OPTIMIZING_INTRINSICS) -#undef INTRINSICS_LIST -#undef OPTIMIZING_INTRINSICS -}; -std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic); - enum IntrinsicNeedsEnvironmentOrCache { kNoEnvironmentOrCache, // Intrinsic does not require an environment or dex cache. kNeedsEnvironmentOrCache // Intrinsic requires an environment or requires a dex cache. diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index c5d761183a..d3a55dd365 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -56,7 +56,6 @@ #include "dead_code_elimination.h" #include "debug/elf_debug_writer.h" #include "debug/method_debug_info.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/verification_results.h" #include "dex/verified_method.h" #include "driver/compiler_driver-inl.h" @@ -479,7 +478,7 @@ static HOptimization* BuildOptimization( } else if (opt_name == InstructionSimplifier::kInstructionSimplifierPassName) { return new (arena) InstructionSimplifier(graph, stats, pass_name.c_str()); } else if (opt_name == IntrinsicsRecognizer::kIntrinsicsRecognizerPassName) { - return new (arena) IntrinsicsRecognizer(graph, driver, stats); + return new (arena) IntrinsicsRecognizer(graph, stats); } else if (opt_name == LICM::kLoopInvariantCodeMotionPassName) { CHECK(most_recent_side_effects != nullptr); return new (arena) LICM(graph, *most_recent_side_effects, stats); @@ -743,7 +742,7 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, graph, stats, "instruction_simplifier$after_bce"); InstructionSimplifier* simplify3 = new (arena) InstructionSimplifier( graph, stats, "instruction_simplifier$before_codegen"); - IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, driver, stats); + IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, stats); HOptimization* optimizations1[] = { intrinsics, @@ -899,7 +898,7 @@ CodeGenerator* OptimizingCompiler::TryCompile(ArenaAllocator* arena, ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(class_loader))); + soa.Decode<mirror::ClassLoader>(class_loader))); method = compiler_driver->ResolveMethod( soa, dex_cache, loader, &dex_compilation_unit, method_idx, invoke_type); } diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h index dd5cb1c9bb..2a23c92f1f 100644 --- a/compiler/optimizing/optimizing_unit_test.h +++ b/compiler/optimizing/optimizing_unit_test.h @@ -22,7 +22,7 @@ #include "common_compiler_test.h" #include "dex_file.h" #include "dex_instruction.h" -#include "handle_scope-inl.h" +#include "handle_scope.h" #include "scoped_thread_state_change.h" #include "ssa_builder.h" #include "ssa_liveness_analysis.h" diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 4289cf7e0f..5a47df1a0d 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -20,7 +20,7 @@ #include "class_linker-inl.h" #include "mirror/class-inl.h" #include "mirror/dex_cache.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/compiler/optimizing/sharpening.cc b/compiler/optimizing/sharpening.cc index abec55f25c..a4a3e0695d 100644 --- a/compiler/optimizing/sharpening.cc +++ b/compiler/optimizing/sharpening.cc @@ -31,7 +31,7 @@ #include "mirror/string.h" #include "nodes.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index 3b2715d56b..5d44cc1b9f 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -49,7 +49,6 @@ #include "compiler_callbacks.h" #include "debug/elf_debug_writer.h" #include "debug/method_debug_info.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/quick_compiler_callbacks.h" #include "dex/verification_results.h" #include "dex_file-inl.h" @@ -77,7 +76,7 @@ #include "runtime.h" #include "runtime_options.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "utils.h" #include "verifier/verifier_deps.h" #include "well_known_classes.h" @@ -509,7 +508,6 @@ class Dex2Oat FINAL { image_patch_delta_(0), key_value_store_(nullptr), verification_results_(nullptr), - method_inliner_map_(), runtime_(nullptr), thread_count_(sysconf(_SC_NPROCESSORS_CONF)), start_ns_(NanoTime()), @@ -1372,7 +1370,6 @@ class Dex2Oat FINAL { verification_results_.reset(new VerificationResults(compiler_options_.get())); callbacks_.reset(new QuickCompilerCallbacks( verification_results_.get(), - &method_inliner_map_, IsBootImage() ? CompilerCallbacks::CallbackMode::kCompileBootImage : CompilerCallbacks::CallbackMode::kCompileApp)); @@ -1567,7 +1564,7 @@ class Dex2Oat FINAL { ScopedObjectAccess soa(self); dex_caches_.push_back(soa.AddLocalReference<jobject>( class_linker->RegisterDexFile(*dex_file, - soa.Decode<mirror::ClassLoader*>(class_loader_)))); + soa.Decode<mirror::ClassLoader>(class_loader_).Decode()))); } return true; @@ -1632,7 +1629,6 @@ class Dex2Oat FINAL { driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - &method_inliner_map_, compiler_kind_, instruction_set_, instruction_set_features_.get(), @@ -2540,7 +2536,6 @@ class Dex2Oat FINAL { std::unique_ptr<VerificationResults> verification_results_; - DexFileToMethodInlinerMap method_inliner_map_; std::unique_ptr<QuickCompilerCallbacks> callbacks_; std::unique_ptr<Runtime> runtime_; diff --git a/imgdiag/imgdiag.cc b/imgdiag/imgdiag.cc index 106cf2fb3b..ace21aa45b 100644 --- a/imgdiag/imgdiag.cc +++ b/imgdiag/imgdiag.cc @@ -34,7 +34,7 @@ #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "image.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "os.h" #include "cmdline.h" diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 06d9814bb2..f3f418d32f 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -57,7 +57,7 @@ #include "oat_file_manager.h" #include "os.h" #include "safe_map.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "stack_map.h" #include "string_reference.h" @@ -2474,7 +2474,7 @@ static int DumpOatWithRuntime(Runtime* runtime, OatFile* oat_file, OatDumperOpti // Use the class loader while dumping. StackHandleScope<1> scope(self); Handle<mirror::ClassLoader> loader_handle = scope.NewHandle( - soa.Decode<mirror::ClassLoader*>(class_loader)); + soa.Decode<mirror::ClassLoader>(class_loader)); options->class_loader_ = &loader_handle; OatDumper oat_dumper(*oat_file, *options); diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc index 1af3660e8f..d58f38cc06 100644 --- a/patchoat/patchoat.cc +++ b/patchoat/patchoat.cc @@ -46,7 +46,7 @@ #include "offsets.h" #include "os.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "utils.h" diff --git a/runtime/arch/instruction_set_features_test.cc b/runtime/arch/instruction_set_features_test.cc index 7bbc709f69..0b8e531896 100644 --- a/runtime/arch/instruction_set_features_test.cc +++ b/runtime/arch/instruction_set_features_test.cc @@ -19,7 +19,7 @@ #include <gtest/gtest.h> #ifdef ART_TARGET_ANDROID -#include "cutils/properties.h" +#include "android-base/properties.h" #endif #include "base/logging.h" @@ -40,8 +40,8 @@ TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyVariant) { // Read the variant property. std::string key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA)); - char dex2oat_isa_variant[PROPERTY_VALUE_MAX]; - if (property_get(key.c_str(), dex2oat_isa_variant, nullptr) > 0) { + std::string dex2oat_isa_variant = android::base::GetProperty(key, ""); + if (!dex2oat_isa_variant.empty()) { // Use features from property to build InstructionSetFeatures and check against build's // features. std::string error_msg; @@ -68,13 +68,13 @@ TEST(InstructionSetFeaturesTest, FeaturesFromSystemPropertyString) { // Read the variant property. std::string variant_key = StringPrintf("dalvik.vm.isa.%s.variant", GetInstructionSetString(kRuntimeISA)); - char dex2oat_isa_variant[PROPERTY_VALUE_MAX]; - if (property_get(variant_key.c_str(), dex2oat_isa_variant, nullptr) > 0) { + std::string dex2oat_isa_variant = android::base::GetProperty(variant_key, ""); + if (!dex2oat_isa_variant.empty()) { // Read the features property. std::string features_key = StringPrintf("dalvik.vm.isa.%s.features", GetInstructionSetString(kRuntimeISA)); - char dex2oat_isa_features[PROPERTY_VALUE_MAX]; - if (property_get(features_key.c_str(), dex2oat_isa_features, nullptr) > 0) { + std::string dex2oat_isa_features = android::base::GetProperty(features_key, ""); + if (!dex2oat_isa_features.empty()) { // Use features from property to build InstructionSetFeatures and check against build's // features. std::string error_msg; diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc index 3424e3c0d2..5e39f42814 100644 --- a/runtime/arch/stub_test.cc +++ b/runtime/arch/stub_test.cc @@ -26,7 +26,7 @@ #include "linear_alloc.h" #include "mirror/class-inl.h" #include "mirror/string-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -1796,7 +1796,7 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type) ScopedObjectAccess soa(self); StackHandleScope<3> hs(self); - Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object*>(o))); + Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object>(o))); Handle<mirror::Class> c(hs.NewHandle(obj->GetClass())); // Need a method as a referrer ArtMethod* m = c->GetDirectMethod(0, kRuntimePointerSize); @@ -1995,11 +1995,11 @@ TEST_F(StubTest, DISABLED_IMT) { jobject jarray_list = env->NewObject(arraylist_jclass, arraylist_constructor); ASSERT_NE(nullptr, jarray_list); - Handle<mirror::Object> array_list(hs.NewHandle(soa.Decode<mirror::Object*>(jarray_list))); + Handle<mirror::Object> array_list(hs.NewHandle(soa.Decode<mirror::Object>(jarray_list))); jobject jobj = env->NewObject(obj_jclass, obj_constructor); ASSERT_NE(nullptr, jobj); - Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object*>(jobj))); + Handle<mirror::Object> obj(hs.NewHandle(soa.Decode<mirror::Object>(jobj))); // Invocation tests. diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h index ef75f941b5..ca96169971 100644 --- a/runtime/art_field-inl.h +++ b/runtime/art_field-inl.h @@ -28,7 +28,7 @@ #include "mirror/object-inl.h" #include "primitive.h" #include "thread-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "well_known_classes.h" namespace art { diff --git a/runtime/art_field.cc b/runtime/art_field.cc index ea5078e9b0..3b4db0bd1e 100644 --- a/runtime/art_field.cc +++ b/runtime/art_field.cc @@ -24,7 +24,7 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "utils.h" #include "well_known_classes.h" diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h index 73cce5ea1a..73c6cf16d4 100644 --- a/runtime/art_method-inl.h +++ b/runtime/art_method-inl.h @@ -36,7 +36,7 @@ #include "quick/quick_method_frame_info.h" #include "read_barrier-inl.h" #include "runtime-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" diff --git a/runtime/art_method.cc b/runtime/art_method.cc index 193bea167f..c97c32837d 100644 --- a/runtime/art_method.cc +++ b/runtime/art_method.cc @@ -40,7 +40,7 @@ #include "mirror/object-inl.h" #include "mirror/string.h" #include "oat_file-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "well_known_classes.h" namespace art { @@ -52,7 +52,7 @@ extern "C" void art_quick_invoke_static_stub(ArtMethod*, uint32_t*, uint32_t, Th ArtMethod* ArtMethod::FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject jlr_method) { - auto* executable = soa.Decode<mirror::Executable*>(jlr_method); + ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable>(jlr_method); DCHECK(executable != nullptr); return executable->GetArtMethod(); } @@ -350,7 +350,7 @@ bool ArtMethod::IsAnnotatedWith(jclass klass, uint32_t visibility) { ScopedObjectAccess soa(self); StackHandleScope<1> shs(self); - mirror::Class* annotation = soa.Decode<mirror::Class*>(klass); + ObjPtr<mirror::Class> annotation = soa.Decode<mirror::Class>(klass); DCHECK(annotation->IsAnnotation()); Handle<mirror::Class> annotation_handle(shs.NewHandle(annotation)); diff --git a/runtime/art_method.h b/runtime/art_method.h index 3d2db690a7..7a8f479d19 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -137,7 +137,52 @@ class ArtMethod FINAL { return (GetAccessFlags() & kAccFinal) != 0; } + bool IsIntrinsic() { + return (GetAccessFlags() & kAccIntrinsic) != 0; + } + + void SetIntrinsic(uint32_t intrinsic) { + DCHECK(IsUint<8>(intrinsic)); + uint32_t new_value = (GetAccessFlags() & kAccFlagsNotUsedByIntrinsic) | + kAccIntrinsic | + (intrinsic << POPCOUNT(kAccFlagsNotUsedByIntrinsic)); + if (kIsDebugBuild) { + uint32_t java_flags = (GetAccessFlags() & kAccJavaFlagsMask); + bool is_constructor = IsConstructor(); + bool is_synchronized = IsSynchronized(); + bool skip_access_checks = SkipAccessChecks(); + bool is_fast_native = IsFastNative(); + bool is_copied = IsCopied(); + bool is_miranda = IsMiranda(); + bool is_default = IsDefault(); + bool is_default_conflict = IsDefaultConflicting(); + bool is_compilable = IsCompilable(); + bool must_count_locks = MustCountLocks(); + SetAccessFlags(new_value); + DCHECK_EQ(java_flags, (GetAccessFlags() & kAccJavaFlagsMask)); + DCHECK_EQ(is_constructor, IsConstructor()); + DCHECK_EQ(is_synchronized, IsSynchronized()); + DCHECK_EQ(skip_access_checks, SkipAccessChecks()); + DCHECK_EQ(is_fast_native, IsFastNative()); + DCHECK_EQ(is_copied, IsCopied()); + DCHECK_EQ(is_miranda, IsMiranda()); + DCHECK_EQ(is_default, IsDefault()); + DCHECK_EQ(is_default_conflict, IsDefaultConflicting()); + DCHECK_EQ(is_compilable, IsCompilable()); + DCHECK_EQ(must_count_locks, MustCountLocks()); + } else { + SetAccessFlags(new_value); + } + } + + uint32_t GetIntrinsic() { + DCHECK(IsIntrinsic()); + return (GetAccessFlags() >> POPCOUNT(kAccFlagsNotUsedByIntrinsic)) & kAccMaxIntrinsic; + } + bool IsCopied() { + static_assert((kAccCopied & kAccFlagsNotUsedByIntrinsic) == kAccCopied, + "kAccCopied conflicts with intrinsic modifier"); const bool copied = (GetAccessFlags() & kAccCopied) != 0; // (IsMiranda() || IsDefaultConflicting()) implies copied DCHECK(!(IsMiranda() || IsDefaultConflicting()) || copied) @@ -146,6 +191,8 @@ class ArtMethod FINAL { } bool IsMiranda() { + static_assert((kAccMiranda & kAccFlagsNotUsedByIntrinsic) == kAccMiranda, + "kAccMiranda conflicts with intrinsic modifier"); return (GetAccessFlags() & kAccMiranda) != 0; } @@ -156,6 +203,9 @@ class ArtMethod FINAL { } bool IsCompilable() { + if (IsIntrinsic()) { + return true; + } return (GetAccessFlags() & kAccCompileDontBother) == 0; } @@ -163,11 +213,16 @@ class ArtMethod FINAL { // multiple default methods. It cannot be invoked, throwing an IncompatibleClassChangeError if one // attempts to do so. bool IsDefaultConflicting() { + if (IsIntrinsic()) { + return false; + } return (GetAccessFlags() & kAccDefaultConflict) != 0u; } // This is set by the class linker. bool IsDefault() { + static_assert((kAccDefault & kAccFlagsNotUsedByIntrinsic) == kAccDefault, + "kAccDefault conflicts with intrinsic modifier"); return (GetAccessFlags() & kAccDefault) != 0; } @@ -204,6 +259,9 @@ class ArtMethod FINAL { // Should this method be run in the interpreter and count locks (e.g., failed structured- // locking verification)? bool MustCountLocks() { + if (IsIntrinsic()) { + return false; + } return (GetAccessFlags() & kAccMustCountLocks) != 0; } diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc index 9d56954445..1183dea7c4 100644 --- a/runtime/base/mutex.cc +++ b/runtime/base/mutex.cc @@ -26,7 +26,7 @@ #include "base/value_object.h" #include "mutex-inl.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h index 8af9fa5c46..91e31d8d0d 100644 --- a/runtime/base/mutex.h +++ b/runtime/base/mutex.h @@ -78,7 +78,6 @@ enum LockLevel { kAllocSpaceLock, kBumpPointerSpaceBlockLock, kArenaPoolLock, - kDexFileMethodInlinerLock, kDexFileToMethodInlinerMapLock, kInternTableLock, kOatFileSecondaryLookupLock, diff --git a/runtime/check_jni.cc b/runtime/check_jni.cc index a980535c40..9f0770285a 100644 --- a/runtime/check_jni.cc +++ b/runtime/check_jni.cc @@ -36,7 +36,7 @@ #include "mirror/string-inl.h" #include "mirror/throwable.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "well_known_classes.h" @@ -269,12 +269,12 @@ class ScopedCheck { */ bool CheckInstanceFieldID(ScopedObjectAccess& soa, jobject java_object, jfieldID fid) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Object* o = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object); if (o == nullptr) { AbortF("field operation on NULL object: %p", java_object); return false; } - if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o)) { + if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(o.Decode())) { Runtime::Current()->GetHeap()->DumpSpaces(LOG_STREAM(ERROR)); AbortF("field operation on invalid %s: %p", ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), @@ -333,15 +333,15 @@ class ScopedCheck { return false; } if (invoke != kVirtual) { - mirror::Class* c = soa.Decode<mirror::Class*>(jc); - if (!m->GetDeclaringClass()->IsAssignableFrom(c)) { + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(jc); + if (!m->GetDeclaringClass()->IsAssignableFrom(c.Decode())) { AbortF("can't call %s %s with class %s", invoke == kStatic ? "static" : "nonvirtual", PrettyMethod(m).c_str(), PrettyClass(c).c_str()); return false; } } if (invoke != kStatic) { - mirror::Object* o = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(jobj); if (o == nullptr) { AbortF("can't call %s on null object", PrettyMethod(m).c_str()); return false; @@ -360,12 +360,12 @@ class ScopedCheck { */ bool CheckStaticFieldID(ScopedObjectAccess& soa, jclass java_class, jfieldID fid) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); ArtField* f = CheckFieldID(soa, fid); if (f == nullptr) { return false; } - if (f->GetDeclaringClass() != c) { + if (c != f->GetDeclaringClass()) { AbortF("static jfieldID %p not valid for class %s", fid, PrettyClass(c).c_str()); return false; } @@ -387,8 +387,8 @@ class ScopedCheck { if (m == nullptr) { return false; } - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); - if (!m->GetDeclaringClass()->IsAssignableFrom(c)) { + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); + if (!m->GetDeclaringClass()->IsAssignableFrom(c.Decode())) { AbortF("can't call static %s on class %s", PrettyMethod(m).c_str(), PrettyClass(c).c_str()); return false; } @@ -408,7 +408,7 @@ class ScopedCheck { if (m == nullptr) { return false; } - mirror::Object* o = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object); if (o == nullptr) { AbortF("can't call %s on null object", PrettyMethod(m).c_str()); return false; @@ -557,14 +557,14 @@ class ScopedCheck { bool CheckReflectedMethod(ScopedObjectAccess& soa, jobject jmethod) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Object* method = soa.Decode<mirror::Object*>(jmethod); + ObjPtr<mirror::Object> method = soa.Decode<mirror::Object>(jmethod); if (method == nullptr) { AbortF("expected non-null method"); return false; } mirror::Class* c = method->GetClass(); - if (soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Method) != c && - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Constructor) != c) { + if (soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Method) != c && + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Constructor) != c) { AbortF("expected java.lang.reflect.Method or " "java.lang.reflect.Constructor but got object of type %s: %p", PrettyTypeOf(method).c_str(), jmethod); @@ -589,13 +589,13 @@ class ScopedCheck { bool CheckReflectedField(ScopedObjectAccess& soa, jobject jfield) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Object* field = soa.Decode<mirror::Object*>(jfield); + ObjPtr<mirror::Object> field = soa.Decode<mirror::Object>(jfield); if (field == nullptr) { AbortF("expected non-null java.lang.reflect.Field"); return false; } mirror::Class* c = field->GetClass(); - if (soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Field) != c) { + if (soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Field) != c) { AbortF("expected java.lang.reflect.Field but got object of type %s: %p", PrettyTypeOf(field).c_str(), jfield); return false; @@ -605,10 +605,10 @@ class ScopedCheck { bool CheckThrowable(ScopedObjectAccess& soa, jthrowable jobj) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); if (!obj->GetClass()->IsThrowableClass()) { AbortF("expected java.lang.Throwable but got object of type " - "%s: %p", PrettyTypeOf(obj).c_str(), obj); + "%s: %p", PrettyTypeOf(obj).c_str(), obj.Decode()); return false; } return true; @@ -616,10 +616,10 @@ class ScopedCheck { bool CheckThrowableClass(ScopedObjectAccess& soa, jclass jc) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = soa.Decode<mirror::Class*>(jc); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(jc); if (!c->IsThrowableClass()) { AbortF("expected java.lang.Throwable class but got object of " - "type %s: %p", PrettyDescriptor(c).c_str(), c); + "type %s: %p", PrettyDescriptor(c).c_str(), c.Decode()); return false; } return true; @@ -647,9 +647,9 @@ class ScopedCheck { bool CheckInstantiableNonArray(ScopedObjectAccess& soa, jclass jc) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = soa.Decode<mirror::Class*>(jc); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(jc); if (!c->IsInstantiableNonArray()) { - AbortF("can't make objects of type %s: %p", PrettyDescriptor(c).c_str(), c); + AbortF("can't make objects of type %s: %p", PrettyDescriptor(c).c_str(), c.Decode()); return false; } return true; @@ -660,7 +660,7 @@ class ScopedCheck { if (!CheckArray(soa, array)) { return false; } - mirror::Array* a = soa.Decode<mirror::Array*>(array); + ObjPtr<mirror::Array> a = soa.Decode<mirror::Array>(array); if (a->GetClass()->GetComponentType()->GetPrimitiveType() != type) { AbortF("incompatible array type %s expected %s[]: %p", PrettyDescriptor(a->GetClass()).c_str(), PrettyDescriptor(type).c_str(), array); @@ -692,20 +692,20 @@ class ScopedCheck { return false; } if (is_static) { - mirror::Object* o = soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj); if (o == nullptr || !o->IsClass()) { AbortF("attempt to access static field %s with a class argument of type %s: %p", PrettyField(field).c_str(), PrettyTypeOf(o).c_str(), fid); return false; } - mirror::Class* c = o->AsClass(); - if (field->GetDeclaringClass() != c) { + ObjPtr<mirror::Class> c = o->AsClass(); + if (c != field->GetDeclaringClass()) { AbortF("attempt to access static field %s with an incompatible class argument of %s: %p", PrettyField(field).c_str(), PrettyDescriptor(c).c_str(), fid); return false; } } else { - mirror::Object* o = soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj); if (o == nullptr || !field->GetDeclaringClass()->IsAssignableFrom(o->GetClass())) { AbortF("attempt to access field %s from an object argument of type %s: %p", PrettyField(field).c_str(), PrettyTypeOf(o).c_str(), fid); @@ -763,7 +763,7 @@ class ScopedCheck { } } - mirror::Object* obj = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_object); if (obj == nullptr) { // Either java_object is invalid or is a cleared weak. IndirectRef ref = reinterpret_cast<IndirectRef>(java_object); @@ -772,12 +772,12 @@ class ScopedCheck { okay = false; } else { obj = soa.Vm()->DecodeWeakGlobal(soa.Self(), ref); - okay = Runtime::Current()->IsClearedJniWeakGlobal(obj); + okay = Runtime::Current()->IsClearedJniWeakGlobal(obj.Decode()); } if (!okay) { AbortF("%s is an invalid %s: %p (%p)", what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), - java_object, obj); + java_object, obj.Decode()); return false; } } @@ -786,7 +786,7 @@ class ScopedCheck { Runtime::Current()->GetHeap()->DumpSpaces(LOG_STREAM(ERROR)); AbortF("%s is an invalid %s: %p (%p)", what, ToStr<IndirectRefKind>(GetIndirectRefKind(java_object)).c_str(), - java_object, obj); + java_object, obj.Decode()); return false; } @@ -936,10 +936,10 @@ class ScopedCheck { break; case 'c': { // jclass jclass jc = arg.c; - mirror::Class* c = soa.Decode<mirror::Class*>(jc); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(jc); if (c == nullptr) { *msg += "NULL"; - } else if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(c)) { + } else if (!Runtime::Current()->GetHeap()->IsValidObjectAddress(c.Decode())) { StringAppendF(msg, "INVALID POINTER:%p", jc); } else if (!c->IsClass()) { *msg += "INVALID NON-CLASS OBJECT OF TYPE:" + PrettyTypeOf(c); @@ -1107,12 +1107,12 @@ class ScopedCheck { return false; } - mirror::Array* a = soa.Decode<mirror::Array*>(java_array); - if (UNLIKELY(!Runtime::Current()->GetHeap()->IsValidObjectAddress(a))) { + ObjPtr<mirror::Array> a = soa.Decode<mirror::Array>(java_array); + if (UNLIKELY(!Runtime::Current()->GetHeap()->IsValidObjectAddress(a.Decode()))) { Runtime::Current()->GetHeap()->DumpSpaces(LOG_STREAM(ERROR)); AbortF("jarray is an invalid %s: %p (%p)", ToStr<IndirectRefKind>(GetIndirectRefKind(java_array)).c_str(), - java_array, a); + java_array, a.Decode()); return false; } else if (!a->IsArrayInstance()) { AbortF("jarray argument has non-array type: %s", PrettyTypeOf(a).c_str()); @@ -1411,7 +1411,7 @@ class GuardedCopy { void* original_ptr) { ScopedObjectAccess soa(env); - mirror::Array* a = soa.Decode<mirror::Array*>(java_array); + ObjPtr<mirror::Array> a = soa.Decode<mirror::Array>(java_array); size_t component_size = a->GetClass()->GetComponentSize(); size_t byte_count = a->GetLength() * component_size; void* result = Create(original_ptr, byte_count, true); diff --git a/runtime/check_reference_map_visitor.h b/runtime/check_reference_map_visitor.h index 843d4c1e2b..ab712f99be 100644 --- a/runtime/check_reference_map_visitor.h +++ b/runtime/check_reference_map_visitor.h @@ -19,7 +19,7 @@ #include "art_method-inl.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack_map.h" namespace art { diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index d5b3090d32..51e5aae3d0 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -67,9 +67,9 @@ inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx, ArtMethod // MethodVerifier refuses methods with string_idx out of bounds. DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());; mirror::String* string = - mirror::StringDexCachePair::LookupString(declaring_class->GetDexCacheStrings(), - string_idx, - mirror::DexCache::kDexCacheStringCacheSize).Read(); + mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(), + string_idx, + mirror::DexCache::kDexCacheStringCacheSize).Read(); Thread::PoisonObjectPointersIfDebug(); if (UNLIKELY(string == nullptr)) { StackHandleScope<1> hs(Thread::Current()); diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index 5106aec31e..0a1f7a940a 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -91,7 +91,7 @@ #include "os.h" #include "runtime.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "trace.h" #include "utils.h" @@ -1085,8 +1085,8 @@ bool ClassLinker::InitFromBootImage(std::string* error_msg) { bool ClassLinker::IsBootClassLoader(ScopedObjectAccessAlreadyRunnable& soa, mirror::ClassLoader* class_loader) { return class_loader == nullptr || - class_loader->GetClass() == - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader); + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader) == + class_loader->GetClass(); } static mirror::String* GetDexPathListElementName(ScopedObjectAccessUnchecked& soa, @@ -1125,8 +1125,8 @@ static bool FlattenPathClassLoader(mirror::ClassLoader* class_loader, CHECK(dex_path_list_field != nullptr); CHECK(dex_elements_field != nullptr); while (!ClassLinker::IsBootClassLoader(soa, class_loader)) { - if (class_loader->GetClass() != - soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)) { + if (soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader) != + class_loader->GetClass()) { *error_msg = StringPrintf("Unknown class loader type %s", PrettyTypeOf(class_loader).c_str()); // Unsupported class loader. return false; @@ -1308,8 +1308,8 @@ bool ClassLinker::UpdateAppImageClassLoadersAndDexCaches( mirror::StringDexCacheType* const strings = reinterpret_cast<mirror::StringDexCacheType*>(raw_arrays + layout.StringsOffset()); for (size_t j = 0; j < num_strings; ++j) { - DCHECK_EQ(strings[j].load(std::memory_order_relaxed).string_index, 0u); - DCHECK(strings[j].load(std::memory_order_relaxed).string_pointer.IsNull()); + DCHECK_EQ(strings[j].load(std::memory_order_relaxed).index, 0u); + DCHECK(strings[j].load(std::memory_order_relaxed).object.IsNull()); strings[j].store(image_resolved_strings[j].load(std::memory_order_relaxed), std::memory_order_relaxed); } @@ -1703,7 +1703,7 @@ bool ClassLinker::AddImageSpace( return false; } // Add the temporary dex path list elements at the end. - auto* elements = soa.Decode<mirror::ObjectArray<mirror::Object>*>(dex_elements); + auto elements = soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements); for (size_t i = 0, num_elems = elements->GetLength(); i < num_elems; ++i) { mirror::Object* element = elements->GetWithoutChecks(i); if (element != nullptr) { @@ -2127,8 +2127,8 @@ mirror::DexCache* ClassLinker::AllocDexCache(Thread* self, if (kIsDebugBuild) { // Sanity check to make sure all the dex cache arrays are empty. b/28992179 for (size_t i = 0; i < num_strings; ++i) { - CHECK_EQ(strings[i].load(std::memory_order_relaxed).string_index, 0u); - CHECK(strings[i].load(std::memory_order_relaxed).string_pointer.IsNull()); + CHECK_EQ(strings[i].load(std::memory_order_relaxed).index, 0u); + CHECK(strings[i].load(std::memory_order_relaxed).object.IsNull()); } for (size_t i = 0; i < dex_file.NumTypeIds(); ++i) { CHECK(types[i].Read<kWithoutReadBarrier>() == nullptr); @@ -2187,7 +2187,7 @@ mirror::Class* ClassLinker::EnsureResolved(Thread* self, const char* descriptor, mirror::Class* klass) { DCHECK(klass != nullptr); - self->PoisonObjectPointers(); + Thread::PoisonObjectPointersIfDebug(); // For temporary classes we must wait for them to be retired. if (init_done_ && klass->IsTemp()) { @@ -2304,8 +2304,8 @@ bool ClassLinker::FindClassInPathClassLoader(ScopedObjectAccessAlreadyRunnable& } // Unsupported class-loader? - if (class_loader->GetClass() != - soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)) { + if (soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader) != + class_loader->GetClass()) { *result = nullptr; return false; } @@ -2482,7 +2482,7 @@ mirror::Class* ClassLinker::FindClass(Thread* self, return nullptr; } else { // success, return mirror::Class* - return soa.Decode<mirror::Class*>(result.get()); + return soa.Decode<mirror::Class>(result.get()).Decode(); } } UNREACHABLE(); @@ -4205,9 +4205,9 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& // Set the class access flags incl. VerificationAttempted, so we do not try to set the flag on // the methods. klass->SetAccessFlags(kAccClassIsProxy | kAccPublic | kAccFinal | kAccVerificationAttempted); - klass->SetClassLoader(soa.Decode<mirror::ClassLoader*>(loader)); + klass->SetClassLoader(soa.Decode<mirror::ClassLoader>(loader).Decode()); DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot); - klass->SetName(soa.Decode<mirror::String*>(name)); + klass->SetName(soa.Decode<mirror::String>(name).Decode()); klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache()); mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self); std::string descriptor(GetDescriptorForProxy(klass.Get())); @@ -4245,7 +4245,7 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& const size_t num_direct_methods = 1; // They have as many virtual methods as the array - auto h_methods = hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Method>*>(methods)); + auto h_methods = hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Method>>(methods)); DCHECK_EQ(h_methods->GetClass(), mirror::Method::ArrayClass()) << PrettyClass(h_methods->GetClass()); const size_t num_virtual_methods = h_methods->GetLength(); @@ -4287,7 +4287,7 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& // Link the fields and virtual methods, creating vtable and iftables. // The new class will replace the old one in the class table. Handle<mirror::ObjectArray<mirror::Class>> h_interfaces( - hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces))); + hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Class>>(interfaces))); if (!LinkClass(self, descriptor.c_str(), klass, h_interfaces, &new_class)) { mirror::Class::SetStatus(klass, mirror::Class::kStatusError, self); return nullptr; @@ -4298,11 +4298,13 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& klass.Assign(new_class.Get()); CHECK_EQ(interfaces_sfield.GetDeclaringClass(), klass.Get()); - interfaces_sfield.SetObject<false>(klass.Get(), - soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces)); + interfaces_sfield.SetObject<false>( + klass.Get(), + soa.Decode<mirror::ObjectArray<mirror::Class>>(interfaces).Decode()); CHECK_EQ(throws_sfield.GetDeclaringClass(), klass.Get()); throws_sfield.SetObject<false>( - klass.Get(), soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >*>(throws)); + klass.Get(), + soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>>(throws).Decode()); { // Lock on klass is released. Lock new class object. @@ -4322,7 +4324,7 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& } StackHandleScope<1> hs2(self); - Handle<mirror::String> decoded_name = hs2.NewHandle(soa.Decode<mirror::String*>(name)); + Handle<mirror::String> decoded_name = hs2.NewHandle(soa.Decode<mirror::String>(name)); std::string interfaces_field_name(StringPrintf("java.lang.Class[] %s.interfaces", decoded_name->ToModifiedUtf8().c_str())); CHECK_EQ(PrettyField(klass->GetStaticField(0)), interfaces_field_name); @@ -4332,9 +4334,9 @@ mirror::Class* ClassLinker::CreateProxyClass(ScopedObjectAccessAlreadyRunnable& CHECK_EQ(PrettyField(klass->GetStaticField(1)), throws_field_name); CHECK_EQ(klass.Get()->GetInterfaces(), - soa.Decode<mirror::ObjectArray<mirror::Class>*>(interfaces)); + soa.Decode<mirror::ObjectArray<mirror::Class>>(interfaces).Decode()); CHECK_EQ(klass.Get()->GetThrows(), - soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>*>(throws)); + soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class>>>(throws).Decode()); } return klass.Get(); } @@ -8193,7 +8195,7 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, // Create PathClassLoader. Handle<mirror::Class> h_path_class_class = hs.NewHandle( - soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)); + soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader)); Handle<mirror::Object> h_path_class_loader = hs.NewHandle( h_path_class_class->AllocObject(self)); DCHECK(h_path_class_loader.Get() != nullptr); @@ -8210,7 +8212,7 @@ jobject ClassLinker::CreatePathClassLoader(Thread* self, "Ljava/lang/ClassLoader;"); DCHECK(parent_field != nullptr); mirror::Object* boot_cl = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self); + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader)->AllocObject(self); parent_field->SetObject<false>(h_path_class_loader.Get(), boot_cl); // Make it a global ref and return. diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 4f73218632..a5aa0d08fe 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -42,7 +42,7 @@ #include "mirror/stack_trace_element.h" #include "mirror/string-inl.h" #include "handle_scope-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { @@ -777,7 +777,7 @@ TEST_F(ClassLinkerTest, FindClassNested) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Nested")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Nested")))); mirror::Class* outer = class_linker_->FindClass(soa.Self(), "LNested;", class_loader); ASSERT_TRUE(outer != nullptr); @@ -811,7 +811,7 @@ TEST_F(ClassLinkerTest, FindClass) { StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass")))); AssertNonExistentClass("LMyClass;"); mirror::Class* MyClass = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader); ASSERT_TRUE(MyClass != nullptr); @@ -937,9 +937,9 @@ TEST_F(ClassLinkerTest, TwoClassLoadersOneClass) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader_1( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass")))); Handle<mirror::ClassLoader> class_loader_2( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("MyClass")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("MyClass")))); mirror::Class* MyClass_1 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_1); mirror::Class* MyClass_2 = class_linker_->FindClass(soa.Self(), "LMyClass;", class_loader_2); EXPECT_TRUE(MyClass_1 != nullptr); @@ -951,7 +951,7 @@ TEST_F(ClassLinkerTest, StaticFields) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Statics")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics")))); Handle<mirror::Class> statics( hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader))); class_linker_->EnsureInitialized(soa.Self(), statics, true, true); @@ -1028,7 +1028,7 @@ TEST_F(ClassLinkerTest, Interfaces) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<6> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Interfaces")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Interfaces")))); Handle<mirror::Class> I( hs.NewHandle(class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader))); Handle<mirror::Class> J( @@ -1097,7 +1097,7 @@ TEST_F(ClassLinkerTest, ResolveVerifyAndClinit) { const DexFile* dex_file = GetFirstDexFile(jclass_loader); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", class_loader); ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize); ArtMethod* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;", kRuntimePointerSize); @@ -1227,7 +1227,7 @@ TEST_F(ClassLinkerTest, Preverified_App) { StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Statics")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics")))); Handle<mirror::Class> statics( hs.NewHandle(class_linker_->FindClass(soa.Self(), "LStatics;", class_loader))); @@ -1242,7 +1242,7 @@ TEST_F(ClassLinkerTest, IsBootStrapClassLoaded) { StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Statics")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Statics")))); // java.lang.Object is a bootstrap class. Handle<mirror::Class> jlo_class( diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc index 11722b2573..eda1ddd87c 100644 --- a/runtime/common_runtime_test.cc +++ b/runtime/common_runtime_test.cc @@ -47,7 +47,7 @@ #include "os.h" #include "primitive.h" #include "runtime-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "well_known_classes.h" @@ -511,12 +511,12 @@ std::vector<const DexFile*> CommonRuntimeTestImpl::GetDexFiles(jobject jclass_lo StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader = hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(jclass_loader)); + soa.Decode<mirror::ClassLoader>(jclass_loader)); DCHECK_EQ(class_loader->GetClass(), - soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)); + soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader).Decode()); DCHECK_EQ(class_loader->GetParent()->GetClass(), - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_BootClassLoader)); + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_BootClassLoader).Decode()); // The class loader is a PathClassLoader which inherits from BaseDexClassLoader. // We need to get the DexPathList and loop through it. diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 6ed44fc5c4..0206caef4c 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -48,7 +48,7 @@ #include "mirror/throwable.h" #include "reflection.h" #include "safe_map.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "ScopedPrimitiveArray.h" #include "handle_scope-inl.h" @@ -390,7 +390,8 @@ static Thread* DecodeThread(ScopedObjectAccessUnchecked& soa, JDWP::ObjectId thr return nullptr; } - mirror::Class* java_lang_Thread = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread); + ObjPtr<mirror::Class> java_lang_Thread = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread); if (!java_lang_Thread->IsAssignableFrom(thread_peer->GetClass())) { // This isn't a thread. *error = JDWP::ERR_INVALID_THREAD; @@ -431,21 +432,22 @@ static JDWP::JdwpTag TagFromClass(const ScopedObjectAccessUnchecked& soa, mirror return JDWP::JT_CLASS_OBJECT; } { - mirror::Class* thread_class = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread); + ObjPtr<mirror::Class> thread_class = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread); if (thread_class->IsAssignableFrom(c)) { return JDWP::JT_THREAD; } } { - mirror::Class* thread_group_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup); + ObjPtr<mirror::Class> thread_group_class = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_ThreadGroup); if (thread_group_class->IsAssignableFrom(c)) { return JDWP::JT_THREAD_GROUP; } } { - mirror::Class* class_loader_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader); + ObjPtr<mirror::Class> class_loader_class = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_ClassLoader); if (class_loader_class->IsAssignableFrom(c)) { return JDWP::JT_CLASS_LOADER; } @@ -1946,7 +1948,8 @@ JDWP::JdwpError Dbg::StringToUtf8(JDWP::ObjectId string_id, std::string* str) { } { ScopedObjectAccessUnchecked soa(Thread::Current()); - mirror::Class* java_lang_String = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_String); + ObjPtr<mirror::Class> java_lang_String = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_String); if (!java_lang_String->IsAssignableFrom(obj->GetClass())) { // This isn't a string. return JDWP::ERR_INVALID_STRING; @@ -2014,7 +2017,7 @@ JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* p expandBufAddObjectId(pReply, JDWP::ObjectId(0)); error = JDWP::ERR_NONE; } else if (error == JDWP::ERR_NONE) { - mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread); CHECK(c != nullptr); ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_group); CHECK(f != nullptr); @@ -2038,7 +2041,8 @@ static mirror::Object* DecodeThreadGroup(ScopedObjectAccessUnchecked& soa, *error = JDWP::ERR_INVALID_OBJECT; return nullptr; } - mirror::Class* c = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ThreadGroup); + ObjPtr<mirror::Class> c = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_ThreadGroup); CHECK(c != nullptr); if (!c->IsAssignableFrom(thread_group->GetClass())) { // This is not a java.lang.ThreadGroup. diff --git a/runtime/dex_file_annotations.cc b/runtime/dex_file_annotations.cc index 789a5bd886..5763479fe3 100644 --- a/runtime/dex_file_annotations.cc +++ b/runtime/dex_file_annotations.cc @@ -255,7 +255,7 @@ mirror::Object* ProcessEncodedAnnotation(Handle<mirror::Class> klass, const uint } mirror::Class* annotation_member_class = - soa.Decode<mirror::Class*>(WellKnownClasses::libcore_reflect_AnnotationMember); + soa.Decode<mirror::Class>(WellKnownClasses::libcore_reflect_AnnotationMember).Decode(); mirror::Class* annotation_member_array_class = class_linker->FindArrayClass(self, &annotation_member_class); if (annotation_member_array_class == nullptr) { @@ -782,7 +782,7 @@ mirror::ObjectArray<mirror::Object>* ProcessAnnotationSet( ScopedObjectAccessUnchecked soa(self); StackHandleScope<2> hs(self); Handle<mirror::Class> annotation_array_class(hs.NewHandle( - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array))); + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array))); if (annotation_set == nullptr) { return mirror::ObjectArray<mirror::Object>::Alloc(self, annotation_array_class.Get(), 0); } @@ -840,7 +840,7 @@ mirror::ObjectArray<mirror::Object>* ProcessAnnotationSetRefList( ScopedObjectAccessUnchecked soa(self); StackHandleScope<1> hs(self); mirror::Class* annotation_array_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array).Decode(); mirror::Class* annotation_array_array_class = Runtime::Current()->GetClassLinker()->FindArrayClass(self, &annotation_array_class); if (annotation_array_array_class == nullptr) { diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc index 8dd5f37962..8e1501ff16 100644 --- a/runtime/dex_file_test.cc +++ b/runtime/dex_file_test.cc @@ -24,7 +24,7 @@ #include "dex_file-inl.h" #include "mem_map.h" #include "os.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" diff --git a/runtime/dex_file_verifier_test.cc b/runtime/dex_file_verifier_test.cc index c5a4d7534c..e39287018a 100644 --- a/runtime/dex_file_verifier_test.cc +++ b/runtime/dex_file_verifier_test.cc @@ -27,7 +27,7 @@ #include "common_runtime_test.h" #include "dex_file-inl.h" #include "leb128.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" diff --git a/runtime/dex_method_iterator_test.cc b/runtime/dex_method_iterator_test.cc index 2681ad0411..9f28c8c803 100644 --- a/runtime/dex_method_iterator_test.cc +++ b/runtime/dex_method_iterator_test.cc @@ -19,7 +19,7 @@ #include "base/stl_util.h" #include "common_runtime_test.h" #include "oat_file.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index bfa2b69045..38ee468f0e 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -33,7 +33,7 @@ #include "nth_caller_visitor.h" #include "oat_quick_method_header.h" #include "reflection.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "well_known_classes.h" namespace art { @@ -165,7 +165,7 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons CHECK(soa.Self()->IsExceptionPending()); return zero; } - soa.Decode<mirror::ObjectArray<mirror::Object>* >(args_jobj)->Set<false>(i, val); + soa.Decode<mirror::ObjectArray<mirror::Object>>(args_jobj)->Set<false>(i, val); } } } @@ -187,13 +187,13 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons return zero; } else { ArtMethod* interface_method = - soa.Decode<mirror::Method*>(interface_method_jobj)->GetArtMethod(); + soa.Decode<mirror::Method>(interface_method_jobj)->GetArtMethod(); // This can cause thread suspension. PointerSize pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize(); mirror::Class* result_type = interface_method->GetReturnType(true /* resolve */, pointer_size); - mirror::Object* result_ref = soa.Decode<mirror::Object*>(result); + ObjPtr<mirror::Object> result_ref = soa.Decode<mirror::Object>(result); JValue result_unboxed; - if (!UnboxPrimitiveForResult(result_ref, result_type, &result_unboxed)) { + if (!UnboxPrimitiveForResult(result_ref.Decode(), result_type, &result_unboxed)) { DCHECK(soa.Self()->IsExceptionPending()); return zero; } @@ -207,9 +207,9 @@ JValue InvokeProxyInvocationHandler(ScopedObjectAccessAlreadyRunnable& soa, cons bool declares_exception = false; { ScopedAssertNoThreadSuspension ants(__FUNCTION__); - mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj); + ObjPtr<mirror::Object> rcvr = soa.Decode<mirror::Object>(rcvr_jobj); mirror::Class* proxy_class = rcvr->GetClass(); - mirror::Method* interface_method = soa.Decode<mirror::Method*>(interface_method_jobj); + ObjPtr<mirror::Method> interface_method = soa.Decode<mirror::Method>(interface_method_jobj); ArtMethod* proxy_method = rcvr->GetClass()->FindVirtualMethodForInterface( interface_method->GetArtMethod(), kRuntimePointerSize); auto virtual_methods = proxy_class->GetVirtualMethodsSlice(kRuntimePointerSize); diff --git a/runtime/entrypoints/jni/jni_entrypoints.cc b/runtime/entrypoints/jni/jni_entrypoints.cc index 22226c1dfb..fd23ced7f7 100644 --- a/runtime/entrypoints/jni/jni_entrypoints.cc +++ b/runtime/entrypoints/jni/jni_entrypoints.cc @@ -18,7 +18,7 @@ #include "base/logging.h" #include "entrypoints/entrypoint_utils.h" #include "mirror/object-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index cfd948ebc5..c52bc8e261 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -36,7 +36,7 @@ #include "oat_quick_method_header.h" #include "quick_exception_handler.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "debugger.h" @@ -834,7 +834,7 @@ void BuildQuickArgumentVisitor::Visit() { void BuildQuickArgumentVisitor::FixupReferences() { // Fixup any references which may have changed. for (const auto& pair : references_) { - pair.second->Assign(soa_->Decode<mirror::Object*>(pair.first)); + pair.second->Assign(soa_->Decode<mirror::Object>(pair.first).Decode()); soa_->Env()->DeleteLocalRef(pair.first); } } @@ -926,7 +926,7 @@ void RememberForGcArgumentVisitor::Visit() { void RememberForGcArgumentVisitor::FixupReferences() { // Fixup any references which may have changed. for (const auto& pair : references_) { - pair.second->Assign(soa_->Decode<mirror::Object*>(pair.first)); + pair.second->Assign(soa_->Decode<mirror::Object>(pair.first).Decode()); soa_->Env()->DeleteLocalRef(pair.first); } } diff --git a/runtime/gc/accounting/card_table_test.cc b/runtime/gc/accounting/card_table_test.cc index 819cb852fa..67ab14ce8e 100644 --- a/runtime/gc/accounting/card_table_test.cc +++ b/runtime/gc/accounting/card_table_test.cc @@ -23,7 +23,7 @@ #include "handle_scope-inl.h" #include "mirror/class-inl.h" #include "mirror/string-inl.h" // Strings are easiest to allocate -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_pool.h" #include "utils.h" diff --git a/runtime/gc/collector/concurrent_copying.cc b/runtime/gc/collector/concurrent_copying.cc index ab8942a4b8..8b910750bd 100644 --- a/runtime/gc/collector/concurrent_copying.cc +++ b/runtime/gc/collector/concurrent_copying.cc @@ -32,7 +32,7 @@ #include "intern_table.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "thread_list.h" #include "well_known_classes.h" diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index ad3dd33303..b89d99c661 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -41,7 +41,7 @@ #include "mark_sweep-inl.h" #include "mirror/object-inl.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "thread_list.h" diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 4e6dd2b13c..88e46249bb 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -61,6 +61,7 @@ #include "intern_table.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" +#include "obj_ptr-inl.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" @@ -69,7 +70,7 @@ #include "reflection.h" #include "runtime.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "handle_scope-inl.h" #include "thread_list.h" #include "well_known_classes.h" @@ -1507,13 +1508,14 @@ void Heap::TrimSpaces(Thread* self) { << static_cast<int>(100 * managed_utilization) << "%."; } -bool Heap::IsValidObjectAddress(const mirror::Object* obj) const { +bool Heap::IsValidObjectAddress(ObjPtr<mirror::Object> obj) const { // Note: we deliberately don't take the lock here, and mustn't test anything that would require // taking the lock. if (obj == nullptr) { return true; } - return IsAligned<kObjectAlignment>(obj) && FindSpaceFromObject(obj, true) != nullptr; + return IsAligned<kObjectAlignment>(obj.Decode()) && + FindSpaceFromObject(obj.Decode(), true) != nullptr; } bool Heap::IsNonDiscontinuousSpaceHeapAddress(const mirror::Object* obj) const { @@ -3565,9 +3567,9 @@ void Heap::SetIdealFootprint(size_t max_allowed_footprint) { max_allowed_footprint_ = max_allowed_footprint; } -bool Heap::IsMovableObject(const mirror::Object* obj) const { +bool Heap::IsMovableObject(ObjPtr<mirror::Object> obj) const { if (kMovingCollector) { - space::Space* space = FindContinuousSpaceFromObject(obj, true); + space::Space* space = FindContinuousSpaceFromObject(obj.Decode(), true); if (space != nullptr) { // TODO: Check large object? return space->CanMoveObjects(); @@ -3727,7 +3729,7 @@ void Heap::AddFinalizerReference(Thread* self, mirror::Object** object) { args[0].l = arg.get(); InvokeWithJValues(soa, nullptr, WellKnownClasses::java_lang_ref_FinalizerReference_add, args); // Restore object in case it gets moved. - *object = soa.Decode<mirror::Object*>(arg.get()); + *object = soa.Decode<mirror::Object>(arg.get()).Decode(); } void Heap::RequestConcurrentGCAndSaveObject(Thread* self, bool force_full, mirror::Object** obj) { diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h index 10bebeff47..e32f05766e 100644 --- a/runtime/gc/heap.h +++ b/runtime/gc/heap.h @@ -34,6 +34,7 @@ #include "gc/collector_type.h" #include "gc/space/large_object_space.h" #include "globals.h" +#include "obj_ptr.h" #include "object_callbacks.h" #include "offsets.h" #include "process_state.h" @@ -274,7 +275,7 @@ class Heap { // A weaker test than IsLiveObject or VerifyObject that doesn't require the heap lock, // and doesn't abort on error, allowing the caller to report more // meaningful diagnostics. - bool IsValidObjectAddress(const mirror::Object* obj) const REQUIRES_SHARED(Locks::mutator_lock_); + bool IsValidObjectAddress(ObjPtr<mirror::Object> obj) const REQUIRES_SHARED(Locks::mutator_lock_); // Faster alternative to IsHeapAddress since finding if an object is in the large object space is // very slow. @@ -290,7 +291,7 @@ class Heap { REQUIRES_SHARED(Locks::heap_bitmap_lock_, Locks::mutator_lock_); // Returns true if there is any chance that the object (obj) will move. - bool IsMovableObject(const mirror::Object* obj) const REQUIRES_SHARED(Locks::mutator_lock_); + bool IsMovableObject(ObjPtr<mirror::Object> obj) const REQUIRES_SHARED(Locks::mutator_lock_); // Enables us to compacting GC until objects are released. void IncrementDisableMovingGC(Thread* self) REQUIRES(!*gc_complete_lock_); diff --git a/runtime/gc/heap_test.cc b/runtime/gc/heap_test.cc index a3cefd9b7f..515a6fd1d8 100644 --- a/runtime/gc/heap_test.cc +++ b/runtime/gc/heap_test.cc @@ -22,7 +22,7 @@ #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace gc { diff --git a/runtime/gc/reference_processor.cc b/runtime/gc/reference_processor.cc index e172f85b19..96945978af 100644 --- a/runtime/gc/reference_processor.cc +++ b/runtime/gc/reference_processor.cc @@ -24,7 +24,7 @@ #include "reference_processor-inl.h" #include "reflection.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "task_processor.h" #include "utils.h" #include "well_known_classes.h" diff --git a/runtime/gc/reference_queue_test.cc b/runtime/gc/reference_queue_test.cc index 2a1635dff9..5b8a3c2963 100644 --- a/runtime/gc/reference_queue_test.cc +++ b/runtime/gc/reference_queue_test.cc @@ -20,7 +20,7 @@ #include "reference_queue.h" #include "handle_scope-inl.h" #include "mirror/class-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace gc { diff --git a/runtime/gc/space/large_object_space.cc b/runtime/gc/space/large_object_space.cc index 16d1f939d7..00303268ff 100644 --- a/runtime/gc/space/large_object_space.cc +++ b/runtime/gc/space/large_object_space.cc @@ -27,7 +27,7 @@ #include "base/stl_util.h" #include "image.h" #include "os.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "space-inl.h" #include "thread-inl.h" diff --git a/runtime/gc/space/space_create_test.cc b/runtime/gc/space/space_create_test.cc index 170f927e9b..7bc4dc40e4 100644 --- a/runtime/gc/space/space_create_test.cc +++ b/runtime/gc/space/space_create_test.cc @@ -18,7 +18,7 @@ #include "dlmalloc_space.h" #include "rosalloc_space.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace gc { diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h index bd600fe9de..17d7c87bd5 100644 --- a/runtime/gc/space/space_test.h +++ b/runtime/gc/space/space_test.h @@ -26,7 +26,7 @@ #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/object-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" #include "zygote_space.h" diff --git a/runtime/gc/system_weak_test.cc b/runtime/gc/system_weak_test.cc index 7c1ec8af4d..af8a444903 100644 --- a/runtime/gc/system_weak_test.cc +++ b/runtime/gc/system_weak_test.cc @@ -26,7 +26,7 @@ #include "handle_scope-inl.h" #include "heap.h" #include "mirror/string.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" namespace art { diff --git a/runtime/gc/task_processor.cc b/runtime/gc/task_processor.cc index a49121b0e6..0704a68d95 100644 --- a/runtime/gc/task_processor.cc +++ b/runtime/gc/task_processor.cc @@ -17,7 +17,7 @@ #include "task_processor.h" #include "base/time_utils.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace gc { diff --git a/runtime/handle_scope-inl.h b/runtime/handle_scope-inl.h index 2e1b8ed3a0..75a0391086 100644 --- a/runtime/handle_scope-inl.h +++ b/runtime/handle_scope-inl.h @@ -21,6 +21,7 @@ #include "base/mutex.h" #include "handle.h" +#include "obj_ptr-inl.h" #include "thread-inl.h" #include "verify_object-inl.h" @@ -107,12 +108,21 @@ inline MutableHandle<T> StackHandleScope<kNumReferences>::NewHandle(T* object) { return h; } +template<size_t kNumReferences> template<class MirrorType, bool kPoison> +inline MutableHandle<MirrorType> StackHandleScope<kNumReferences>::NewHandle( + ObjPtr<MirrorType, kPoison> object) { + return NewHandle(object.Decode()); +} + template<size_t kNumReferences> template<class T> inline HandleWrapper<T> StackHandleScope<kNumReferences>::NewHandleWrapper(T** object) { - SetReference(pos_, *object); - MutableHandle<T> h(GetHandle<T>(pos_)); - pos_++; - return HandleWrapper<T>(object, h); + return HandleWrapper<T>(object, NewHandle(*object)); +} + +template<size_t kNumReferences> template<class T> +inline HandleWrapperObjPtr<T> StackHandleScope<kNumReferences>::NewHandleWrapper( + ObjPtr<T>* object) { + return HandleWrapperObjPtr<T>(object, NewHandle(*object)); } template<size_t kNumReferences> diff --git a/runtime/handle_scope.h b/runtime/handle_scope.h index 37eed993ea..2b283ae3df 100644 --- a/runtime/handle_scope.h +++ b/runtime/handle_scope.h @@ -28,6 +28,9 @@ #include "verify_object.h" namespace art { + +template<class MirrorType, bool kPoison> class ObjPtr; + namespace mirror { class Object; } @@ -125,7 +128,7 @@ class PACKED(4) HandleScope { }; // A wrapper which wraps around Object** and restores the pointer in the destructor. -// TODO: Add more functionality. +// TODO: Delete template<class T> class HandleWrapper : public MutableHandle<T> { public: @@ -143,6 +146,26 @@ class HandleWrapper : public MutableHandle<T> { T** const obj_; }; + +// A wrapper which wraps around ObjPtr<Object>* and restores the pointer in the destructor. +// TODO: Add more functionality. +template<class T> +class HandleWrapperObjPtr : public MutableHandle<T> { + public: + HandleWrapperObjPtr(ObjPtr<T>* obj, const MutableHandle<T>& handle) + : MutableHandle<T>(handle), obj_(obj) {} + + HandleWrapperObjPtr(const HandleWrapperObjPtr&) = default; + + ~HandleWrapperObjPtr() { + *obj_ = ObjPtr<T>(MutableHandle<T>::Get()); + } + + private: + ObjPtr<T>* const obj_; +}; + + // Scoped handle storage of a fixed size that is usually stack allocated. template<size_t kNumReferences> class PACKED(4) StackHandleScope FINAL : public HandleScope { @@ -157,6 +180,14 @@ class PACKED(4) StackHandleScope FINAL : public HandleScope { ALWAYS_INLINE HandleWrapper<T> NewHandleWrapper(T** object) REQUIRES_SHARED(Locks::mutator_lock_); + template<class T> + ALWAYS_INLINE HandleWrapperObjPtr<T> NewHandleWrapper(ObjPtr<T>* object) + REQUIRES_SHARED(Locks::mutator_lock_); + + template<class MirrorType, bool kPoison> + ALWAYS_INLINE MutableHandle<MirrorType> NewHandle(ObjPtr<MirrorType, kPoison> object) + REQUIRES_SHARED(Locks::mutator_lock_); + ALWAYS_INLINE void SetReference(size_t i, mirror::Object* object) REQUIRES_SHARED(Locks::mutator_lock_); diff --git a/runtime/handle_scope_test.cc b/runtime/handle_scope_test.cc index 58f3800e8f..c269a37f8d 100644 --- a/runtime/handle_scope_test.cc +++ b/runtime/handle_scope_test.cc @@ -17,7 +17,7 @@ #include "base/enums.h" #include "gtest/gtest.h" #include "handle_scope-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc index 921dde1fe6..ecb2157833 100644 --- a/runtime/hprof/hprof.cc +++ b/runtime/hprof/hprof.cc @@ -59,7 +59,7 @@ #include "mirror/object-inl.h" #include "os.h" #include "safe_map.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" namespace art { diff --git a/runtime/image.cc b/runtime/image.cc index 7e6790a551..299d5fd13f 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -25,7 +25,7 @@ namespace art { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '0', '\0' }; +const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '1', '\0' }; ImageHeader::ImageHeader(uint32_t image_begin, uint32_t image_size, diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc index 1f39a1e695..202e472685 100644 --- a/runtime/indirect_reference_table.cc +++ b/runtime/indirect_reference_table.cc @@ -21,7 +21,7 @@ #include "nth_caller_visitor.h" #include "reference_table.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "utils.h" #include "verify_object-inl.h" diff --git a/runtime/indirect_reference_table_test.cc b/runtime/indirect_reference_table_test.cc index 61bcadd798..58d487d14a 100644 --- a/runtime/indirect_reference_table_test.cc +++ b/runtime/indirect_reference_table_test.cc @@ -19,7 +19,7 @@ #include "class_linker-inl.h" #include "common_runtime_test.h" #include "mirror/object-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/instrumentation_test.cc b/runtime/instrumentation_test.cc index abe3184427..7f9f04f435 100644 --- a/runtime/instrumentation_test.cc +++ b/runtime/instrumentation_test.cc @@ -25,7 +25,7 @@ #include "handle_scope-inl.h" #include "jvalue.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" #include "thread-inl.h" @@ -458,7 +458,7 @@ TEST_F(InstrumentationTest, DeoptimizeDirectMethod) { instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); ClassLinker* class_linker = runtime->GetClassLinker(); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); + Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader); ASSERT_TRUE(klass != nullptr); ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V", @@ -505,7 +505,7 @@ TEST_F(InstrumentationTest, MixedDeoptimization) { instrumentation::Instrumentation* instr = runtime->GetInstrumentation(); ClassLinker* class_linker = runtime->GetClassLinker(); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); + Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); mirror::Class* klass = class_linker->FindClass(soa.Self(), "LInstrumentation;", loader); ASSERT_TRUE(klass != nullptr); ArtMethod* method_to_deoptimize = klass->FindDeclaredDirectMethod("instanceMethod", "()V", diff --git a/runtime/intern_table_test.cc b/runtime/intern_table_test.cc index 620e15b508..74cec57498 100644 --- a/runtime/intern_table_test.cc +++ b/runtime/intern_table_test.cc @@ -20,7 +20,7 @@ #include "mirror/object.h" #include "handle_scope-inl.h" #include "mirror/string.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/interpreter/interpreter.cc b/runtime/interpreter/interpreter.cc index 0003e72428..c270df748c 100644 --- a/runtime/interpreter/interpreter.cc +++ b/runtime/interpreter/interpreter.cc @@ -23,7 +23,7 @@ #include "interpreter_mterp_impl.h" #include "interpreter_switch_impl.h" #include "mirror/string-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "stack.h" #include "unstarted_runtime.h" @@ -51,7 +51,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), klass.get()); } - result->SetL(soa.Decode<Object*>(jresult)); + result->SetL(soa.Decode<Object>(jresult).Decode()); } else if (shorty == "V") { typedef void (fntype)(JNIEnv*, jclass); fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); @@ -93,7 +93,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), klass.get(), arg0.get()); } - result->SetL(soa.Decode<Object*>(jresult)); + result->SetL(soa.Decode<Object>(jresult).Decode()); } else if (shorty == "IIZ") { typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); @@ -191,7 +191,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), rcvr.get()); } - result->SetL(soa.Decode<Object*>(jresult)); + result->SetL(soa.Decode<Object>(jresult).Decode()); } else if (shorty == "V") { typedef void (fntype)(JNIEnv*, jobject); fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); @@ -212,7 +212,7 @@ static void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& s ScopedThreadStateChange tsc(self, kNative); jresult = fn(soa.Env(), rcvr.get(), arg0.get()); } - result->SetL(soa.Decode<Object*>(jresult)); + result->SetL(soa.Decode<Object>(jresult).Decode()); ScopedThreadStateChange tsc(self, kNative); } else if (shorty == "III") { typedef jint (fntype)(JNIEnv*, jobject, jint, jint); diff --git a/runtime/interpreter/interpreter_common.h b/runtime/interpreter/interpreter_common.h index 814adf7132..0feb013e5b 100644 --- a/runtime/interpreter/interpreter_common.h +++ b/runtime/interpreter/interpreter_common.h @@ -254,9 +254,9 @@ static inline String* ResolveString(Thread* self, ShadowFrame& shadow_frame, uin DCHECK_LT(string_idx % mirror::DexCache::kDexCacheStringCacheSize, declaring_class->GetDexFile().NumStringIds()); mirror::String* string_ptr = - mirror::StringDexCachePair::LookupString(declaring_class->GetDexCacheStrings(), - string_idx, - mirror::DexCache::kDexCacheStringCacheSize).Read(); + mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(), + string_idx, + mirror::DexCache::kDexCacheStringCacheSize).Read(); if (UNLIKELY(string_ptr == nullptr)) { StackHandleScope<1> hs(self); Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache())); diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc index 98e358b8b8..39846da467 100644 --- a/runtime/interpreter/unstarted_runtime.cc +++ b/runtime/interpreter/unstarted_runtime.cc @@ -1619,9 +1619,9 @@ void UnstartedRuntime::UnstartedJNIThrowableNativeFillInStackTrace( uint32_t* args ATTRIBUTE_UNUSED, JValue* result) { ScopedObjectAccessUnchecked soa(self); if (Runtime::Current()->IsActiveTransaction()) { - result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<true>(soa))); + result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<true>(soa)).Decode()); } else { - result->SetL(soa.Decode<mirror::Object*>(self->CreateInternalStackTrace<false>(soa))); + result->SetL(soa.Decode<mirror::Object>(self->CreateInternalStackTrace<false>(soa)).Decode()); } } diff --git a/runtime/interpreter/unstarted_runtime_test.cc b/runtime/interpreter/unstarted_runtime_test.cc index ba751ec94c..6a4add3bb8 100644 --- a/runtime/interpreter/unstarted_runtime_test.cc +++ b/runtime/interpreter/unstarted_runtime_test.cc @@ -31,7 +31,7 @@ #include "mirror/class_loader.h" #include "mirror/string-inl.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "transaction.h" diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc index 979495ab9e..0c752ef4fe 100644 --- a/runtime/java_vm_ext.cc +++ b/runtime/java_vm_ext.cc @@ -36,7 +36,7 @@ #include "runtime-inl.h" #include "runtime_options.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "thread_list.h" @@ -532,17 +532,17 @@ bool JavaVMExt::ShouldTrace(ArtMethod* method) { return true; } -jobject JavaVMExt::AddGlobalRef(Thread* self, mirror::Object* obj) { +jobject JavaVMExt::AddGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) { // Check for null after decoding the object to handle cleared weak globals. if (obj == nullptr) { return nullptr; } WriterMutexLock mu(self, globals_lock_); - IndirectRef ref = globals_.Add(IRT_FIRST_SEGMENT, obj); + IndirectRef ref = globals_.Add(IRT_FIRST_SEGMENT, obj.Decode()); return reinterpret_cast<jobject>(ref); } -jweak JavaVMExt::AddWeakGlobalRef(Thread* self, mirror::Object* obj) { +jweak JavaVMExt::AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) { if (obj == nullptr) { return nullptr; } @@ -550,7 +550,7 @@ jweak JavaVMExt::AddWeakGlobalRef(Thread* self, mirror::Object* obj) { while (UNLIKELY(!MayAccessWeakGlobals(self))) { weak_globals_add_condition_.WaitHoldingLocks(self); } - IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj); + IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj.Decode()); return reinterpret_cast<jweak>(ref); } @@ -755,15 +755,15 @@ bool JavaVMExt::LoadNativeLibrary(JNIEnv* env, ScopedObjectAccess soa(env); // As the incoming class loader is reachable/alive during the call of this function, // it's okay to decode it without worrying about unexpectedly marking it alive. - mirror::ClassLoader* loader = soa.Decode<mirror::ClassLoader*>(class_loader); + ObjPtr<mirror::ClassLoader> loader = soa.Decode<mirror::ClassLoader>(class_loader); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); - if (class_linker->IsBootClassLoader(soa, loader)) { + if (class_linker->IsBootClassLoader(soa, loader.Decode())) { loader = nullptr; class_loader = nullptr; } - class_loader_allocator = class_linker->GetAllocatorForClassLoader(loader); + class_loader_allocator = class_linker->GetAllocatorForClassLoader(loader.Decode()); CHECK(class_loader_allocator != nullptr); } if (library != nullptr) { diff --git a/runtime/java_vm_ext.h b/runtime/java_vm_ext.h index a10a72fa94..558ffffe5a 100644 --- a/runtime/java_vm_ext.h +++ b/runtime/java_vm_ext.h @@ -22,6 +22,7 @@ #include "base/macros.h" #include "base/mutex.h" #include "indirect_reference_table.h" +#include "obj_ptr.h" #include "reference_table.h" namespace art { @@ -123,10 +124,10 @@ class JavaVMExt : public JavaVM { void BroadcastForNewWeakGlobals() REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_); - jobject AddGlobalRef(Thread* self, mirror::Object* obj) + jobject AddGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!globals_lock_); - jweak AddWeakGlobalRef(Thread* self, mirror::Object* obj) + jweak AddWeakGlobalRef(Thread* self, ObjPtr<mirror::Object> obj) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!weak_globals_lock_); void DeleteGlobalRef(Thread* self, jobject obj) REQUIRES(!globals_lock_); diff --git a/runtime/jdwp/jdwp_event.cc b/runtime/jdwp/jdwp_event.cc index e2d29fe270..6aebe9f9d1 100644 --- a/runtime/jdwp/jdwp_event.cc +++ b/runtime/jdwp/jdwp_event.cc @@ -30,7 +30,7 @@ #include "jdwp/jdwp_expand_buf.h" #include "jdwp/jdwp_priv.h" #include "jdwp/object_registry.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "handle_scope-inl.h" diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc index f6008acdf1..0f2d188bca 100644 --- a/runtime/jdwp/jdwp_handler.cc +++ b/runtime/jdwp/jdwp_handler.cc @@ -31,7 +31,7 @@ #include "jdwp/jdwp_expand_buf.h" #include "jdwp/jdwp_priv.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" diff --git a/runtime/jdwp/jdwp_main.cc b/runtime/jdwp/jdwp_main.cc index dbf04fe7a1..e3bf3e5a9d 100644 --- a/runtime/jdwp/jdwp_main.cc +++ b/runtime/jdwp/jdwp_main.cc @@ -25,7 +25,7 @@ #include "base/time_utils.h" #include "debugger.h" #include "jdwp/jdwp_priv.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/jdwp/object_registry.cc b/runtime/jdwp/object_registry.cc index 5989b6148b..9ba62c93cd 100644 --- a/runtime/jdwp/object_registry.cc +++ b/runtime/jdwp/object_registry.cc @@ -19,7 +19,7 @@ #include "handle_scope-inl.h" #include "jni_internal.h" #include "mirror/class.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc index c9227b1bbd..2c6b249302 100644 --- a/runtime/jit/jit_code_cache.cc +++ b/runtime/jit/jit_code_cache.cc @@ -32,7 +32,7 @@ #include "linear_alloc.h" #include "mem_map.h" #include "oat_file-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" namespace art { diff --git a/runtime/jit/profile_compilation_info_test.cc b/runtime/jit/profile_compilation_info_test.cc index c8f4d94c74..764458aece 100644 --- a/runtime/jit/profile_compilation_info_test.cc +++ b/runtime/jit/profile_compilation_info_test.cc @@ -26,7 +26,7 @@ #include "mirror/class_loader.h" #include "handle_scope-inl.h" #include "jit/offline_profiling_info.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/jit/profile_saver.cc b/runtime/jit/profile_saver.cc index a4bc3fca47..d23821bb71 100644 --- a/runtime/jit/profile_saver.cc +++ b/runtime/jit/profile_saver.cc @@ -26,7 +26,7 @@ #include "base/time_utils.h" #include "compiler_filter.h" #include "oat_file_manager.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/jit/profiling_info.cc b/runtime/jit/profiling_info.cc index 216df2fc09..6ba187ec73 100644 --- a/runtime/jit/profiling_info.cc +++ b/runtime/jit/profiling_info.cc @@ -20,7 +20,7 @@ #include "dex_instruction.h" #include "jit/jit.h" #include "jit/jit_code_cache.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc index a11f9ab31f..7b2757897e 100644 --- a/runtime/jni_internal.cc +++ b/runtime/jni_internal.cc @@ -52,7 +52,7 @@ #include "reflection.h" #include "runtime.h" #include "safe_map.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "thread.h" #include "utf.h" @@ -108,7 +108,7 @@ static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror:: "%s is null at index %d", kind, idx); } -static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass) +static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) { if (LIKELY(klass->IsInitialized())) { return klass; @@ -124,7 +124,7 @@ static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass) static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class, const char* name, const char* sig, bool is_static) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class)); + ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class)); if (c == nullptr) { return nullptr; } @@ -143,31 +143,31 @@ static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class, } } if (method == nullptr || method->IsStatic() != is_static) { - ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static"); + ThrowNoSuchMethodError(soa, c.Decode(), name, sig, is_static ? "static" : "non-static"); return nullptr; } return soa.EncodeMethod(method); } -static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa) +static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa) REQUIRES_SHARED(Locks::mutator_lock_) { ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr); // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set. if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) { - return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride()); + return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride()); } // If we have a method, use its ClassLoader for context. if (method != nullptr) { return method->GetDeclaringClass()->GetClassLoader(); } // We don't have a method, so try to use the system ClassLoader. - mirror::ClassLoader* class_loader = - soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader()); + ObjPtr<mirror::ClassLoader> class_loader = + soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader()); if (class_loader != nullptr) { return class_loader; } // See if the override ClassLoader is set for gtests. - class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride()); + class_loader = soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride()); if (class_loader != nullptr) { // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an // image. @@ -184,7 +184,7 @@ static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, con REQUIRES_SHARED(Locks::mutator_lock_) { StackHandleScope<2> hs(soa.Self()); Handle<mirror::Class> c( - hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class)))); + hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class)))); if (c.Get() == nullptr) { return nullptr; } @@ -272,7 +272,7 @@ int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobj if (mid == nullptr) { ScopedObjectAccess soa(env); LOG(ERROR) << "No <init>" << signature << " in " - << PrettyClass(soa.Decode<mirror::Class*>(exception_class)); + << PrettyClass(soa.Decode<mirror::Class>(exception_class)); return JNI_ERR; } @@ -282,7 +282,7 @@ int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobj return JNI_ERR; } ScopedObjectAccess soa(env); - soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get())); + soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()).Decode()); return JNI_OK; } @@ -363,12 +363,12 @@ class JNI { static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) { CHECK_NON_NULL_ARGUMENT(jlr_field); ScopedObjectAccess soa(env); - mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field); + ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field); if (obj_field->GetClass() != mirror::Field::StaticClass()) { // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary? return nullptr; } - auto* field = static_cast<mirror::Field*>(obj_field); + ObjPtr<mirror::Field> field = down_cast<mirror::Field*>(obj_field.Decode()); return soa.EncodeField(field->GetArtField()); } @@ -398,14 +398,14 @@ class JNI { static jclass GetObjectClass(JNIEnv* env, jobject java_object) { CHECK_NON_NULL_ARGUMENT(java_object); ScopedObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object); return soa.AddLocalReference<jclass>(o->GetClass()); } static jclass GetSuperclass(JNIEnv* env, jclass java_class) { CHECK_NON_NULL_ARGUMENT(java_class); ScopedObjectAccess soa(env); - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass()); } @@ -415,9 +415,9 @@ class JNI { CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE); CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE); ScopedObjectAccess soa(env); - mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1); - mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2); - return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE; + ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1); + ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2); + return c2->IsAssignableFrom(c1.Decode()) ? JNI_TRUE : JNI_FALSE; } static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) { @@ -427,19 +427,19 @@ class JNI { return JNI_TRUE; } else { ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(jobj); - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE; } } static jint Throw(JNIEnv* env, jthrowable java_exception) { ScopedObjectAccess soa(env); - mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception); + ObjPtr<mirror::Throwable> exception = soa.Decode<mirror::Throwable>(java_exception); if (exception == nullptr) { return JNI_ERR; } - soa.Self()->SetException(exception); + soa.Self()->SetException(exception.Decode()); return JNI_OK; } @@ -509,7 +509,7 @@ class JNI { static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) { ScopedObjectAccess soa(env); - mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor); + ObjPtr<mirror::Object> survivor = soa.Decode<mirror::Object>(java_survivor); soa.Env()->PopFrame(); return soa.AddLocalReference<jobject>(survivor); } @@ -522,8 +522,8 @@ class JNI { static jobject NewGlobalRef(JNIEnv* env, jobject obj) { ScopedObjectAccess soa(env); - mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj); - return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj); + ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj); + return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj.Decode()); } static void DeleteGlobalRef(JNIEnv* env, jobject obj) { @@ -534,8 +534,8 @@ class JNI { static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) { ScopedObjectAccess soa(env); - mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj); - return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj); + ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj); + return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj.Decode()); } static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) { @@ -546,7 +546,7 @@ class JNI { static jobject NewLocalRef(JNIEnv* env, jobject obj) { ScopedObjectAccess soa(env); - mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj); // Check for null after decoding the object to handle cleared weak globals. if (decoded_obj == nullptr) { return nullptr; @@ -579,7 +579,7 @@ class JNI { return JNI_TRUE; } else { ScopedObjectAccess soa(env); - return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2)) + return (soa.Decode<mirror::Object>(obj1) == soa.Decode<mirror::Object>(obj2)) ? JNI_TRUE : JNI_FALSE; } } @@ -587,7 +587,7 @@ class JNI { static jobject AllocObject(JNIEnv* env, jclass java_class) { CHECK_NON_NULL_ARGUMENT(java_class); ScopedObjectAccess soa(env); - mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class)); + ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(java_class)); if (c == nullptr) { return nullptr; } @@ -613,7 +613,8 @@ class JNI { CHECK_NON_NULL_ARGUMENT(java_class); CHECK_NON_NULL_ARGUMENT(mid); ScopedObjectAccess soa(env); - mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class)); + ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), + soa.Decode<mirror::Class>(java_class)); if (c == nullptr) { return nullptr; } @@ -639,7 +640,8 @@ class JNI { CHECK_NON_NULL_ARGUMENT(java_class); CHECK_NON_NULL_ARGUMENT(mid); ScopedObjectAccess soa(env); - mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class)); + ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), + soa.Decode<mirror::Class>(java_class)); if (c == nullptr) { return nullptr; } @@ -1223,9 +1225,9 @@ class JNI { CHECK_NON_NULL_ARGUMENT(obj); CHECK_NON_NULL_ARGUMENT(fid); ScopedObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj); ArtField* f = soa.DecodeField(fid); - return soa.AddLocalReference<jobject>(f->GetObject(o)); + return soa.AddLocalReference<jobject>(f->GetObject(o.Decode())); } static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) { @@ -1239,27 +1241,27 @@ class JNI { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object); CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); ScopedObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_object); - mirror::Object* v = soa.Decode<mirror::Object*>(java_value); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object); + ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value); ArtField* f = soa.DecodeField(fid); - f->SetObject<false>(o, v); + f->SetObject<false>(o.Decode(), v.Decode()); } static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); ScopedObjectAccess soa(env); - mirror::Object* v = soa.Decode<mirror::Object*>(java_value); + ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value); ArtField* f = soa.DecodeField(fid); - f->SetObject<false>(f->GetDeclaringClass(), v); + f->SetObject<false>(f->GetDeclaringClass(), v.Decode()); } #define GET_PRIMITIVE_FIELD(fn, instance) \ CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \ CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \ ScopedObjectAccess soa(env); \ - mirror::Object* o = soa.Decode<mirror::Object*>(instance); \ + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \ ArtField* f = soa.DecodeField(fid); \ - return f->Get ##fn (o) + return f->Get ##fn (o.Decode()) #define GET_STATIC_PRIMITIVE_FIELD(fn) \ CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \ @@ -1271,9 +1273,9 @@ class JNI { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \ CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \ ScopedObjectAccess soa(env); \ - mirror::Object* o = soa.Decode<mirror::Object*>(instance); \ + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \ ArtField* f = soa.DecodeField(fid); \ - f->Set ##fn <false>(o, value) + f->Set ##fn <false>(o.Decode(), value) #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \ CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \ @@ -1657,20 +1659,20 @@ class JNI { static jsize GetStringLength(JNIEnv* env, jstring java_string) { CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string); ScopedObjectAccess soa(env); - return soa.Decode<mirror::String*>(java_string)->GetLength(); + return soa.Decode<mirror::String>(java_string)->GetLength(); } static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) { CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string); ScopedObjectAccess soa(env); - return soa.Decode<mirror::String*>(java_string)->GetUtfLength(); + return soa.Decode<mirror::String>(java_string)->GetUtfLength(); } static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length, jchar* buf) { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string); ScopedObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); if (start < 0 || length < 0 || length > s->GetLength() - start) { ThrowSIOOBE(soa, start, length, s->GetLength()); } else { @@ -1690,7 +1692,7 @@ class JNI { char* buf) { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string); ScopedObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); if (start < 0 || length < 0 || length > s->GetLength() - start) { ThrowSIOOBE(soa, start, length, s->GetLength()); } else { @@ -1710,7 +1712,7 @@ class JNI { static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) { CHECK_NON_NULL_ARGUMENT(java_string); ScopedObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); gc::Heap* heap = Runtime::Current()->GetHeap(); if (heap->IsMovableObject(s) || s->IsCompressed()) { jchar* chars = new jchar[s->GetLength()]; @@ -1736,7 +1738,7 @@ class JNI { static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string); ScopedObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) { delete[] chars; } @@ -1745,11 +1747,11 @@ class JNI { static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) { CHECK_NON_NULL_ARGUMENT(java_string); ScopedObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); gc::Heap* heap = Runtime::Current()->GetHeap(); if (heap->IsMovableObject(s)) { StackHandleScope<1> hs(soa.Self()); - HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s)); + HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s)); if (!kUseReadBarrier) { heap->IncrementDisableMovingGC(soa.Self()); } else { @@ -1782,7 +1784,7 @@ class JNI { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string); ScopedObjectAccess soa(env); gc::Heap* heap = Runtime::Current()->GetHeap(); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); if (heap->IsMovableObject(s)) { if (!kUseReadBarrier) { heap->DecrementDisableMovingGC(soa.Self()); @@ -1803,7 +1805,7 @@ class JNI { *is_copy = JNI_TRUE; } ScopedObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_string); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string); size_t byte_count = s->GetUtfLength(); char* bytes = new char[byte_count + 1]; CHECK(bytes != nullptr); // bionic aborts anyway. @@ -1826,7 +1828,7 @@ class JNI { static jsize GetArrayLength(JNIEnv* env, jarray java_array) { CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array); ScopedObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(java_array); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_array); if (UNLIKELY(!obj->IsArrayInstance())) { soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str()); return 0; @@ -1838,8 +1840,8 @@ class JNI { static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) { CHECK_NON_NULL_ARGUMENT(java_array); ScopedObjectAccess soa(env); - mirror::ObjectArray<mirror::Object>* array = - soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array); + ObjPtr<mirror::ObjectArray<mirror::Object>> array = + soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array); return soa.AddLocalReference<jobject>(array->Get(index)); } @@ -1847,10 +1849,10 @@ class JNI { jobject java_value) { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array); ScopedObjectAccess soa(env); - mirror::ObjectArray<mirror::Object>* array = - soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array); - mirror::Object* value = soa.Decode<mirror::Object*>(java_value); - array->Set<false>(index, value); + ObjPtr<mirror::ObjectArray<mirror::Object>> array = + soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array); + ObjPtr<mirror::Object> value = soa.Decode<mirror::Object>(java_value); + array->Set<false>(index, value.Decode()); } static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) { @@ -1893,7 +1895,7 @@ class JNI { ScopedObjectAccess soa(env); mirror::Class* array_class; { - mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass); + mirror::Class* element_class = soa.Decode<mirror::Class>(element_jclass).Decode(); if (UNLIKELY(element_class->IsPrimitive())) { soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s", PrettyDescriptor(element_class).c_str()); @@ -1910,7 +1912,7 @@ class JNI { mirror::ObjectArray<mirror::Object>* result = mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length); if (result != nullptr && initial_element != nullptr) { - mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element); + ObjPtr<mirror::Object> initial_object = soa.Decode<mirror::Object>(initial_element); if (initial_object != nullptr) { mirror::Class* element_class = result->GetClass()->GetComponentType(); if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) { @@ -1921,7 +1923,7 @@ class JNI { return nullptr; } else { for (jsize i = 0; i < length; ++i) { - result->SetWithoutChecks<false>(i, initial_object); + result->SetWithoutChecks<false>(i, initial_object.Decode()); } } } @@ -1936,7 +1938,7 @@ class JNI { static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) { CHECK_NON_NULL_ARGUMENT(java_array); ScopedObjectAccess soa(env); - mirror::Array* array = soa.Decode<mirror::Array*>(java_array); + ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array); if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) { soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s", PrettyDescriptor(array->GetClass()).c_str()); @@ -1952,7 +1954,7 @@ class JNI { heap->IncrementDisableThreadFlip(soa.Self()); } // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete. - array = soa.Decode<mirror::Array*>(java_array); + array = soa.Decode<mirror::Array>(java_array); } if (is_copy != nullptr) { *is_copy = JNI_FALSE; @@ -1964,14 +1966,14 @@ class JNI { jint mode) { CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array); ScopedObjectAccess soa(env); - mirror::Array* array = soa.Decode<mirror::Array*>(java_array); + ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array); if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) { soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s", PrettyDescriptor(array->GetClass()).c_str()); return; } const size_t component_size = array->GetClass()->GetComponentSize(); - ReleasePrimitiveArray(soa, array, component_size, elements, mode); + ReleasePrimitiveArray(soa, array.Decode(), component_size, elements, mode); } static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) { @@ -2145,7 +2147,7 @@ class JNI { } CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR); ScopedObjectAccess soa(env); - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); if (UNLIKELY(method_count == 0)) { LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for " << PrettyDescriptor(c); @@ -2157,13 +2159,13 @@ class JNI { const char* sig = methods[i].signature; const void* fnPtr = methods[i].fnPtr; if (UNLIKELY(name == nullptr)) { - ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors); + ReportInvalidJNINativeMethod(soa, c.Decode(), "method name", i, return_errors); return JNI_ERR; } else if (UNLIKELY(sig == nullptr)) { - ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors); + ReportInvalidJNINativeMethod(soa, c.Decode(), "method signature", i, return_errors); return JNI_ERR; } else if (UNLIKELY(fnPtr == nullptr)) { - ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors); + ReportInvalidJNINativeMethod(soa, c.Decode(), "native function", i, return_errors); return JNI_ERR; } bool is_fast = false; @@ -2206,17 +2208,17 @@ class JNI { // the parent. ArtMethod* m = nullptr; bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled(); - for (mirror::Class* current_class = c; + for (ObjPtr<mirror::Class> current_class = c; current_class != nullptr; current_class = current_class->GetSuperClass()) { // Search first only comparing methods which are native. - m = FindMethod<true>(current_class, name, sig); + m = FindMethod<true>(current_class.Decode(), name, sig); if (m != nullptr) { break; } // Search again comparing to all methods, to find non-native methods that match. - m = FindMethod<false>(current_class, name, sig); + m = FindMethod<false>(current_class.Decode(), name, sig); if (m != nullptr) { break; } @@ -2238,14 +2240,14 @@ class JNI { << "Failed to register native method " << PrettyDescriptor(c) << "." << name << sig << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8(); - ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static"); + ThrowNoSuchMethodError(soa, c.Decode(), name, sig, "static or non-static"); return JNI_ERR; } else if (!m->IsNative()) { LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL) << "Failed to register non-native method " << PrettyDescriptor(c) << "." << name << sig << " as native"; - ThrowNoSuchMethodError(soa, c, name, sig, "native"); + ThrowNoSuchMethodError(soa, c.Decode(), name, sig, "native"); return JNI_ERR; } @@ -2260,7 +2262,7 @@ class JNI { static jint UnregisterNatives(JNIEnv* env, jclass java_class) { CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR); ScopedObjectAccess soa(env); - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]"; @@ -2283,24 +2285,24 @@ class JNI { static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS { CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR); ScopedObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object); o = o->MonitorEnter(soa.Self()); if (soa.Self()->IsExceptionPending()) { return JNI_ERR; } - soa.Env()->monitors.Add(o); + soa.Env()->monitors.Add(o.Decode()); return JNI_OK; } static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS { CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR); ScopedObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object); o->MonitorExit(soa.Self()); if (soa.Self()->IsExceptionPending()) { return JNI_ERR; } - soa.Env()->monitors.Remove(o); + soa.Env()->monitors.Remove(o.Decode()); return JNI_OK; } @@ -2409,7 +2411,7 @@ class JNI { static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array, const char* fn_name, const char* operation) REQUIRES_SHARED(Locks::mutator_lock_) { - ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array); + ObjPtr<ArtArrayT> array = soa.Decode<ArtArrayT>(java_array); if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) { soa.Vm()->JniAbortF(fn_name, "attempt to %s %s primitive array elements with an object of type %s", @@ -2419,7 +2421,7 @@ class JNI { return nullptr; } DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize()); - return array; + return array.Decode(); } template <typename ArrayT, typename ElementT, typename ArtArrayT> diff --git a/runtime/jni_internal_test.cc b/runtime/jni_internal_test.cc index fe0081c2d4..9bd6f6d8c0 100644 --- a/runtime/jni_internal_test.cc +++ b/runtime/jni_internal_test.cc @@ -22,7 +22,7 @@ #include "java_vm_ext.h" #include "jni_env_ext.h" #include "mirror/string-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" namespace art { @@ -58,7 +58,7 @@ class JniInternalTest : public CommonCompilerTest { void ExpectException(jclass exception_class) { ScopedObjectAccess soa(env_); EXPECT_TRUE(env_->ExceptionCheck()) - << PrettyDescriptor(soa.Decode<mirror::Class*>(exception_class)); + << PrettyDescriptor(soa.Decode<mirror::Class>(exception_class)); jthrowable exception = env_->ExceptionOccurred(); EXPECT_NE(nullptr, exception); env_->ExceptionClear(); @@ -619,7 +619,7 @@ class JniInternalTest : public CommonCompilerTest { class_loader_ = LoadDex("MyClassNatives"); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader_))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); mirror::Class* c = class_linker_->FindClass(soa.Self(), "LMyClassNatives;", loader); const auto pointer_size = class_linker_->GetImagePointerSize(); ArtMethod* method = direct ? c->FindDirectMethod(method_name, method_sig, pointer_size) : @@ -1598,7 +1598,7 @@ TEST_F(JniInternalTest, GetStringUTFChars_ReleaseStringUTFChars) { TEST_F(JniInternalTest, GetStringChars_ReleaseStringChars) { jstring s = env_->NewStringUTF("hello"); ScopedObjectAccess soa(env_); - mirror::String* s_m = soa.Decode<mirror::String*>(s); + ObjPtr<mirror::String> s_m = soa.Decode<mirror::String>(s); ASSERT_TRUE(s != nullptr); jchar expected[] = { 'h', 'e', 'l', 'l', 'o' }; @@ -2236,7 +2236,7 @@ TEST_F(JniInternalTest, MonitorExitNotAllUnlocked) { static bool IsLocked(JNIEnv* env, jobject jobj) { ScopedObjectAccess soa(env); - LockWord lock_word = soa.Decode<mirror::Object*>(jobj)->GetLockWord(true); + LockWord lock_word = soa.Decode<mirror::Object>(jobj)->GetLockWord(true); switch (lock_word.GetState()) { case LockWord::kHashCode: case LockWord::kUnlocked: diff --git a/runtime/jobject_comparator.cc b/runtime/jobject_comparator.cc index 1f424b34c1..443f095d05 100644 --- a/runtime/jobject_comparator.cc +++ b/runtime/jobject_comparator.cc @@ -19,7 +19,7 @@ #include "mirror/array-inl.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -32,8 +32,8 @@ bool JobjectComparator::operator()(jobject jobj1, jobject jobj2) const { } ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); - Handle<mirror::Object> obj1(hs.NewHandle(soa.Decode<mirror::Object*>(jobj1))); - Handle<mirror::Object> obj2(hs.NewHandle(soa.Decode<mirror::Object*>(jobj2))); + Handle<mirror::Object> obj1(hs.NewHandle(soa.Decode<mirror::Object>(jobj1))); + Handle<mirror::Object> obj2(hs.NewHandle(soa.Decode<mirror::Object>(jobj2))); if (obj1.Get() == nullptr) { return true; } else if (obj2.Get() == nullptr) { diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h index 548087e729..6c1259bf50 100644 --- a/runtime/mirror/class.h +++ b/runtime/mirror/class.h @@ -54,9 +54,10 @@ class Constructor; class DexCache; class IfTable; class Method; -struct StringDexCachePair; +template <typename T> struct PACKED(8) DexCachePair; -using StringDexCacheType = std::atomic<mirror::StringDexCachePair>; +using StringDexCachePair = DexCachePair<mirror::String>; +using StringDexCacheType = std::atomic<StringDexCachePair>; // C++ mirror of java.lang.Class class MANAGED Class FINAL : public Object { diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index 220979a152..359462d21a 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -39,7 +39,7 @@ inline uint32_t DexCache::ClassSize(PointerSize pointer_size) { inline mirror::String* DexCache::GetResolvedString(uint32_t string_idx) { DCHECK_LT(string_idx, GetDexFile()->NumStringIds()); - return StringDexCachePair::LookupString(GetStrings(), string_idx, NumStrings()).Read(); + return StringDexCachePair::Lookup(GetStrings(), string_idx, NumStrings()).Read(); } inline void DexCache::SetResolvedString(uint32_t string_idx, mirror::String* resolved) { @@ -61,10 +61,10 @@ inline void DexCache::ClearString(uint32_t string_idx) { DCHECK(Runtime::Current()->IsAotCompiler()); StringDexCacheType* slot = &GetStrings()[slot_idx]; // This is racy but should only be called from the transactional interpreter. - if (slot->load(std::memory_order_relaxed).string_index == string_idx) { + if (slot->load(std::memory_order_relaxed).index == string_idx) { StringDexCachePair cleared( nullptr, - StringDexCachePair::InvalidStringIndexForSlot(slot_idx)); + StringDexCachePair::InvalidIndexForSlot(slot_idx)); slot->store(cleared, std::memory_order_relaxed); } } @@ -155,11 +155,11 @@ inline void DexCache::VisitReferences(mirror::Class* klass, const Visitor& visit mirror::StringDexCacheType* strings = GetStrings(); for (size_t i = 0, num_strings = NumStrings(); i != num_strings; ++i) { StringDexCachePair source = strings[i].load(std::memory_order_relaxed); - mirror::String* before = source.string_pointer.Read<kReadBarrierOption>(); + mirror::String* before = source.object.Read<kReadBarrierOption>(); GcRoot<mirror::String> root(before); visitor.VisitRootIfNonNull(root.AddressWithoutBarrier()); if (root.Read() != before) { - source.string_pointer = GcRoot<String>(root.Read()); + source.object = GcRoot<String>(root.Read()); strings[i].store(source, std::memory_order_relaxed); } } @@ -175,9 +175,9 @@ inline void DexCache::FixupStrings(mirror::StringDexCacheType* dest, const Visit mirror::StringDexCacheType* src = GetStrings(); for (size_t i = 0, count = NumStrings(); i < count; ++i) { StringDexCachePair source = src[i].load(std::memory_order_relaxed); - mirror::String* ptr = source.string_pointer.Read<kReadBarrierOption>(); + mirror::String* ptr = source.object.Read<kReadBarrierOption>(); mirror::String* new_source = visitor(ptr); - source.string_pointer = GcRoot<String>(new_source); + source.object = GcRoot<String>(new_source); dest[i].store(source, std::memory_order_relaxed); } } diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 7d4021fe68..d81dedc538 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -35,9 +35,9 @@ namespace mirror { class String; -struct PACKED(8) StringDexCachePair { - GcRoot<String> string_pointer; - uint32_t string_index; +template <typename T> struct PACKED(8) DexCachePair { + GcRoot<T> object; + uint32_t index; // The array is initially [ {0,0}, {0,0}, {0,0} ... ] // We maintain the invariant that once a dex cache entry is populated, // the pointer is always non-0 @@ -45,47 +45,51 @@ struct PACKED(8) StringDexCachePair { // {non-0, non-0} OR {0,0} // // It's generally sufficiently enough then to check if the - // lookup string index matches the stored string index (for a >0 string index) + // lookup index matches the stored index (for a >0 lookup index) // because if it's true the pointer is also non-null. // // For the 0th entry which is a special case, the value is either // {0,0} (initial state) or {non-0, 0} which indicates - // that a valid string is stored at that index for a dex string id of 0. + // that a valid object is stored at that index for a dex section id of 0. // - // As an optimization, we want to avoid branching on the string pointer since - // it's always non-null if the string id branch succeeds (except for the 0th string id). + // As an optimization, we want to avoid branching on the object pointer since + // it's always non-null if the id branch succeeds (except for the 0th id). // Set the initial state for the 0th entry to be {0,1} which is guaranteed to fail - // the lookup string id == stored id branch. - StringDexCachePair(String* string, uint32_t string_idx) - : string_pointer(string), - string_index(string_idx) {} - StringDexCachePair() = default; - StringDexCachePair(const StringDexCachePair&) = default; - StringDexCachePair& operator=(const StringDexCachePair&) = default; - - static void Initialize(StringDexCacheType* strings) { - mirror::StringDexCachePair first_elem; - first_elem.string_pointer = GcRoot<String>(nullptr); - first_elem.string_index = InvalidStringIndexForSlot(0); - strings[0].store(first_elem, std::memory_order_relaxed); + // the lookup id == stored id branch. + DexCachePair(T* object, uint32_t index) + : object(object), + index(index) {} + DexCachePair() = default; + DexCachePair(const DexCachePair<T>&) = default; + DexCachePair& operator=(const DexCachePair<T>&) = default; + + static void Initialize(std::atomic<DexCachePair<T>>* dex_cache) { + DexCachePair<T> first_elem; + first_elem.object = GcRoot<T>(nullptr); + first_elem.index = InvalidIndexForSlot(0); + dex_cache[0].store(first_elem, std::memory_order_relaxed); } - static GcRoot<String> LookupString(StringDexCacheType* dex_cache, - uint32_t string_idx, - uint32_t cache_size) { - StringDexCachePair index_string = dex_cache[string_idx % cache_size] - .load(std::memory_order_relaxed); - if (string_idx != index_string.string_index) return GcRoot<String>(nullptr); - DCHECK(!index_string.string_pointer.IsNull()); - return index_string.string_pointer; + static GcRoot<T> Lookup(std::atomic<DexCachePair<T>>* dex_cache, + uint32_t idx, + uint32_t cache_size) { + DexCachePair<T> element = dex_cache[idx % cache_size].load(std::memory_order_relaxed); + if (idx != element.index) { + return GcRoot<T>(nullptr); + } + + DCHECK(!element.object.IsNull()); + return element.object; } - static uint32_t InvalidStringIndexForSlot(uint32_t slot) { + static uint32_t InvalidIndexForSlot(uint32_t slot) { // Since the cache size is a power of two, 0 will always map to slot 0. // Use 1 for slot 0 and 0 for all other slots. return (slot == 0) ? 1u : 0u; } }; + +using StringDexCachePair = DexCachePair<mirror::String>; using StringDexCacheType = std::atomic<StringDexCachePair>; // C++ mirror of java.lang.DexCache. diff --git a/runtime/mirror/dex_cache_test.cc b/runtime/mirror/dex_cache_test.cc index 43ba362aca..ac04200e22 100644 --- a/runtime/mirror/dex_cache_test.cc +++ b/runtime/mirror/dex_cache_test.cc @@ -24,7 +24,7 @@ #include "mirror/class_loader-inl.h" #include "mirror/dex_cache-inl.h" #include "handle_scope-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace mirror { @@ -56,7 +56,7 @@ TEST_F(DexCacheTest, LinearAlloc) { ClassLinker* const class_linker = runtime->GetClassLinker(); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(jclass_loader))); + soa.Decode<mirror::ClassLoader>(jclass_loader))); mirror::Class* klass = class_linker->FindClass(soa.Self(), "LMain;", class_loader); ASSERT_TRUE(klass != nullptr); LinearAlloc* const linear_alloc = klass->GetClassLoader()->GetAllocator(); @@ -72,7 +72,7 @@ TEST_F(DexCacheTest, TestResolvedFieldAccess) { ClassLinker* const class_linker = runtime->GetClassLinker(); StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader(hs.NewHandle( - soa.Decode<mirror::ClassLoader*>(jclass_loader))); + soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> klass1 = hs.NewHandle(class_linker->FindClass(soa.Self(), "Lpackage1/Package1;", class_loader)); ASSERT_TRUE(klass1.Get() != nullptr); diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc index 0f3447e5b0..40ee3a2e50 100644 --- a/runtime/mirror/object_test.cc +++ b/runtime/mirror/object_test.cc @@ -38,7 +38,7 @@ #include "obj_ptr.h" #include "object-inl.h" #include "object_array-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "string-inl.h" namespace art { @@ -365,7 +365,7 @@ TEST_F(ObjectTest, StaticFieldFromCode) { const DexFile* dex_file = GetFirstDexFile(class_loader); StackHandleScope<2> hs(soa.Self()); - Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<ClassLoader*>(class_loader))); + Handle<mirror::ClassLoader> loader(hs.NewHandle(soa.Decode<ClassLoader>(class_loader))); Class* klass = class_linker_->FindClass(soa.Self(), "LStaticsFromCode;", loader); ArtMethod* clinit = klass->FindClassInitializer(kRuntimePointerSize); const DexFile::TypeId* klass_type_id = dex_file->FindTypeId("LStaticsFromCode;"); @@ -495,8 +495,8 @@ TEST_F(ObjectTest, DescriptorCompare) { jobject jclass_loader_1 = LoadDex("ProtoCompare"); jobject jclass_loader_2 = LoadDex("ProtoCompare2"); StackHandleScope<4> hs(soa.Self()); - Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader_1))); - Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader_2))); + Handle<ClassLoader> class_loader_1(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_1))); + Handle<ClassLoader> class_loader_2(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader_2))); Class* klass1 = linker->FindClass(soa.Self(), "LProtoCompare;", class_loader_1); ASSERT_TRUE(klass1 != nullptr); @@ -538,7 +538,7 @@ TEST_F(ObjectTest, InstanceOf) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); StackHandleScope<3> hs(soa.Self()); - Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader))); + Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader); Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader); @@ -575,7 +575,7 @@ TEST_F(ObjectTest, IsAssignableFrom) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); StackHandleScope<1> hs(soa.Self()); - Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader))); + Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader); Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader); @@ -613,7 +613,7 @@ TEST_F(ObjectTest, IsAssignableFromArray) { ScopedObjectAccess soa(Thread::Current()); jobject jclass_loader = LoadDex("XandY"); StackHandleScope<1> hs(soa.Self()); - Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader))); + Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); Class* X = class_linker_->FindClass(soa.Self(), "LX;", class_loader); Class* Y = class_linker_->FindClass(soa.Self(), "LY;", class_loader); ASSERT_TRUE(X != nullptr); @@ -752,7 +752,7 @@ TEST_F(ObjectTest, ObjectPointer) { EXPECT_FALSE(null_ptr != null_ptr); EXPECT_FALSE(null_ptr != nullptr); null_ptr.AssertValid(); - Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader*>(jclass_loader))); + Handle<ClassLoader> class_loader(hs.NewHandle(soa.Decode<ClassLoader>(jclass_loader))); Handle<mirror::Class> h_X( hs.NewHandle(class_linker_->FindClass(soa.Self(), "LX;", class_loader))); ObjPtr<Class, /*kPoison*/ true> X(h_X.Get()); diff --git a/runtime/modifiers.h b/runtime/modifiers.h index fd7a125bc3..dd32df69d7 100644 --- a/runtime/modifiers.h +++ b/runtime/modifiers.h @@ -67,6 +67,7 @@ static constexpr uint32_t kAccCompileDontBother = 0x01000000; // method (ru // Set by the verifier for a method that could not be verified to follow structured locking. static constexpr uint32_t kAccMustCountLocks = 0x02000000; // method (runtime) +static constexpr uint32_t kAccIntrinsic = 0x80000000; // method (runtime) // Special runtime-only flags. // Interface and all its super-interfaces with default methods have been recursively initialized. @@ -76,6 +77,9 @@ static constexpr uint32_t kAccHasDefaultMethod = 0x40000000; // class/ancestor overrides finalize() static constexpr uint32_t kAccClassIsFinalizable = 0x80000000; +static constexpr uint32_t kAccFlagsNotUsedByIntrinsic = 0x007FFFFF; +static constexpr uint32_t kAccMaxIntrinsic = 0xFF; + // Valid (meaningful) bits for a field. static constexpr uint32_t kAccValidFieldFlags = kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccFinal | kAccVolatile | kAccTransient | kAccSynthetic | kAccEnum; diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 49b83a719d..3bc1b06741 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -30,7 +30,7 @@ #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "thread_list.h" #include "verifier/method_verifier.h" diff --git a/runtime/monitor_pool_test.cc b/runtime/monitor_pool_test.cc index e1837f52ab..a111c6c16a 100644 --- a/runtime/monitor_pool_test.cc +++ b/runtime/monitor_pool_test.cc @@ -17,7 +17,7 @@ #include "monitor_pool.h" #include "common_runtime_test.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { diff --git a/runtime/monitor_test.cc b/runtime/monitor_test.cc index ac6a4f3744..4ee46dcdff 100644 --- a/runtime/monitor_test.cc +++ b/runtime/monitor_test.cc @@ -27,7 +27,7 @@ #include "mirror/class-inl.h" #include "mirror/string-inl.h" // Strings are easiest to allocate #include "object_lock.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_pool.h" namespace art { diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc index 384de34909..0677d5bf04 100644 --- a/runtime/native/dalvik_system_DexFile.cc +++ b/runtime/native/dalvik_system_DexFile.cc @@ -34,7 +34,7 @@ #include "oat_file_manager.h" #include "os.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" #include "utils.h" @@ -217,7 +217,7 @@ static jboolean DexFile_closeDexFile(JNIEnv* env, jclass, jobject cookie) { bool all_deleted = true; { ScopedObjectAccess soa(env); - mirror::Object* dex_files_object = soa.Decode<mirror::Object*>(cookie); + ObjPtr<mirror::Object> dex_files_object = soa.Decode<mirror::Object>(cookie); mirror::LongArray* long_dex_files = dex_files_object->AsLongArray(); // Delete dex files associated with this dalvik.system.DexFile since there should not be running // code using it. dex_files is a vector due to multidex. @@ -277,7 +277,7 @@ static jclass DexFile_defineClassNative(JNIEnv* env, ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(javaLoader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader))); class_linker->RegisterDexFile(*dex_file, class_loader.Get()); mirror::Class* result = class_linker->DefineClass(soa.Self(), descriptor.c_str(), @@ -287,7 +287,7 @@ static jclass DexFile_defineClassNative(JNIEnv* env, *dex_class_def); // Add the used dex file. This only required for the DexFile.loadClass API since normal // class loaders already keep their dex files live. - class_linker->InsertDexFileInToClassLoader(soa.Decode<mirror::Object*>(dexFile), + class_linker->InsertDexFileInToClassLoader(soa.Decode<mirror::Object>(dexFile).Decode(), class_loader.Get()); if (result != nullptr) { VLOG(class_linker) << "DexFile_defineClassNative returning " << result diff --git a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc index 94933bce32..fdced21110 100644 --- a/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc +++ b/runtime/native/dalvik_system_InMemoryDexClassLoader_DexData.cc @@ -24,7 +24,7 @@ #include "mirror/class_loader.h" #include "mirror/object-inl.h" #include "oat_file.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" namespace art { @@ -148,7 +148,7 @@ static jclass InMemoryDexClassLoader_DexData_findClass( ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); StackHandleScope<1> handle_scope(soa.Self()); Handle<mirror::ClassLoader> class_loader( - handle_scope.NewHandle(soa.Decode<mirror::ClassLoader*>(loader))); + handle_scope.NewHandle(soa.Decode<mirror::ClassLoader>(loader))); class_linker->RegisterDexFile(*dex_file, class_loader.Get()); mirror::Class* result = class_linker->DefineClass( soa.Self(), class_descriptor, hash, class_loader, *dex_file, *dex_class_def); @@ -157,7 +157,7 @@ static jclass InMemoryDexClassLoader_DexData_findClass( // InMemoryClassLoader/DexData instance now that a class has // been loaded. class_linker->InsertDexFileInToClassLoader( - soa.Decode<mirror::Object*>(dexData), class_loader.Get()); + soa.Decode<mirror::Object>(dexData).Decode(), class_loader.Get()); return soa.AddLocalReference<jclass>(result); } } diff --git a/runtime/native/dalvik_system_VMDebug.cc b/runtime/native/dalvik_system_VMDebug.cc index f09c067cfd..73c466411f 100644 --- a/runtime/native/dalvik_system_VMDebug.cc +++ b/runtime/native/dalvik_system_VMDebug.cc @@ -36,7 +36,7 @@ #include "mirror/class.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "trace.h" #include "well_known_classes.h" @@ -259,11 +259,11 @@ static jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass ScopedObjectAccess soa(env); gc::Heap* const heap = Runtime::Current()->GetHeap(); // Caller's responsibility to do GC if desired. - mirror::Class* c = soa.Decode<mirror::Class*>(javaClass); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(javaClass); if (c == nullptr) { return 0; } - std::vector<mirror::Class*> classes {c}; + std::vector<mirror::Class*> classes {c.Decode()}; uint64_t count = 0; heap->CountInstances(classes, countAssignable, &count); return count; @@ -274,7 +274,8 @@ static jlongArray VMDebug_countInstancesOfClasses(JNIEnv* env, jclass, jobjectAr ScopedObjectAccess soa(env); gc::Heap* const heap = Runtime::Current()->GetHeap(); // Caller's responsibility to do GC if desired. - auto* decoded_classes = soa.Decode<mirror::ObjectArray<mirror::Class>*>(javaClasses); + ObjPtr<mirror::ObjectArray<mirror::Class>> decoded_classes = + soa.Decode<mirror::ObjectArray<mirror::Class>>(javaClasses); if (decoded_classes == nullptr) { return nullptr; } diff --git a/runtime/native/dalvik_system_VMRuntime.cc b/runtime/native/dalvik_system_VMRuntime.cc index d88c9d4750..c7fb44ecec 100644 --- a/runtime/native/dalvik_system_VMRuntime.cc +++ b/runtime/native/dalvik_system_VMRuntime.cc @@ -46,8 +46,8 @@ extern "C" void android_set_application_target_sdk_version(uint32_t version); #include "mirror/dex_cache-inl.h" #include "mirror/object-inl.h" #include "runtime.h" -#include "scoped_fast_native_object_access.h" -#include "scoped_thread_state_change.h" +#include "scoped_fast_native_object_access-inl.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "thread_list.h" @@ -74,7 +74,7 @@ static jobject VMRuntime_newNonMovableArray(JNIEnv* env, jobject, jclass javaEle ThrowNegativeArraySizeException(length); return nullptr; } - mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass); + mirror::Class* element_class = soa.Decode<mirror::Class>(javaElementClass).Decode(); if (UNLIKELY(element_class == nullptr)) { ThrowNullPointerException("element class == null"); return nullptr; @@ -99,7 +99,7 @@ static jobject VMRuntime_newUnpaddedArray(JNIEnv* env, jobject, jclass javaEleme ThrowNegativeArraySizeException(length); return nullptr; } - mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass); + mirror::Class* element_class = soa.Decode<mirror::Class>(javaElementClass).Decode(); if (UNLIKELY(element_class == nullptr)) { ThrowNullPointerException("element class == null"); return nullptr; @@ -122,12 +122,12 @@ static jlong VMRuntime_addressOf(JNIEnv* env, jobject, jobject javaArray) { return 0; } ScopedFastNativeObjectAccess soa(env); - mirror::Array* array = soa.Decode<mirror::Array*>(javaArray); + ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(javaArray); if (!array->IsArrayInstance()) { ThrowIllegalArgumentException("not an array"); return 0; } - if (Runtime::Current()->GetHeap()->IsMovableObject(array)) { + if (Runtime::Current()->GetHeap()->IsMovableObject(array.Decode())) { ThrowRuntimeException("Trying to get address of movable array object"); return 0; } diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc index 9da40b971a..0dd8cdd2d9 100644 --- a/runtime/native/dalvik_system_VMStack.cc +++ b/runtime/native/dalvik_system_VMStack.cc @@ -22,8 +22,8 @@ #include "mirror/class-inl.h" #include "mirror/class_loader.h" #include "mirror/object-inl.h" -#include "scoped_fast_native_object_access.h" -#include "scoped_thread_state_change.h" +#include "scoped_fast_native_object_access-inl.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" namespace art { @@ -31,7 +31,7 @@ namespace art { static jobject GetThreadStack(const ScopedFastNativeObjectAccess& soa, jobject peer) REQUIRES_SHARED(Locks::mutator_lock_) { jobject trace = nullptr; - if (soa.Decode<mirror::Object*>(peer) == soa.Self()->GetPeer()) { + if (soa.Decode<mirror::Object>(peer) == soa.Self()->GetPeer()) { trace = soa.Self()->CreateInternalStackTrace<false>(soa); } else { // Suspend thread to build stack trace. diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc index fe3cbe74f5..a78909b879 100644 --- a/runtime/native/dalvik_system_ZygoteHooks.cc +++ b/runtime/native/dalvik_system_ZygoteHooks.cc @@ -24,7 +24,7 @@ #include "jit/jit.h" #include "jni_internal.h" #include "JNIHelp.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "thread-inl.h" #include "trace.h" diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc index b6260e9486..34bd57b090 100644 --- a/runtime/native/java_lang_Class.cc +++ b/runtime/native/java_lang_Class.cc @@ -35,8 +35,8 @@ #include "mirror/string-inl.h" #include "obj_ptr-inl.h" #include "reflection.h" -#include "scoped_thread_state_change.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_thread_state_change-inl.h" +#include "scoped_fast_native_object_access-inl.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" #include "utf.h" @@ -44,10 +44,10 @@ namespace art { -ALWAYS_INLINE static inline mirror::Class* DecodeClass( +ALWAYS_INLINE static inline ObjPtr<mirror::Class> DecodeClass( const ScopedFastNativeObjectAccess& soa, jobject java_class) REQUIRES_SHARED(Locks::mutator_lock_) { - mirror::Class* c = soa.Decode<mirror::Class*>(java_class); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class); DCHECK(c != nullptr); DCHECK(c->IsClass()); // TODO: we could EnsureInitialized here, rather than on every reflective get/set or invoke . @@ -76,16 +76,19 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean std::string descriptor(DotToDescriptor(name.c_str())); StackHandleScope<2> hs(soa.Self()); - Handle<mirror::ClassLoader> class_loader(hs.NewHandle(soa.Decode<mirror::ClassLoader*>(javaLoader))); + Handle<mirror::ClassLoader> class_loader( + hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader))); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); Handle<mirror::Class> c( hs.NewHandle(class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader))); if (c.Get() == nullptr) { ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred()); env->ExceptionClear(); - jthrowable cnfe = reinterpret_cast<jthrowable>(env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException, - WellKnownClasses::java_lang_ClassNotFoundException_init, - javaName, cause.get())); + jthrowable cnfe = reinterpret_cast<jthrowable>( + env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException, + WellKnownClasses::java_lang_ClassNotFoundException_init, + javaName, + cause.get())); if (cnfe != nullptr) { // Make sure allocation didn't fail with an OOME. env->Throw(cnfe); @@ -101,18 +104,18 @@ static jclass Class_classForName(JNIEnv* env, jclass, jstring javaName, jboolean static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - mirror::Class* const c = DecodeClass(soa, javaThis); + ObjPtr<mirror::Class> c = DecodeClass(soa, javaThis); return soa.AddLocalReference<jstring>(mirror::Class::ComputeName(hs.NewHandle(c))); } static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); - mirror::Class* c = DecodeClass(soa, javaThis); + ObjPtr<mirror::Class> c = DecodeClass(soa, javaThis); return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone(soa.Self())); } static mirror::ObjectArray<mirror::Field>* GetDeclaredFields( - Thread* self, mirror::Class* klass, bool public_only, bool force_resolve) + Thread* self, ObjPtr<mirror::Class> klass, bool public_only, bool force_resolve) REQUIRES_SHARED(Locks::mutator_lock_) { StackHandleScope<1> hs(self); IterationRange<StrideIterator<ArtField>> ifields = klass->GetIFields(); @@ -192,8 +195,8 @@ static jobjectArray Class_getPublicDeclaredFields(JNIEnv* env, jobject javaThis) // Performs a binary search through an array of fields, TODO: Is this fast enough if we don't use // the dex cache for lookups? I think CompareModifiedUtf8ToUtf16AsCodePointValues should be fairly // fast. -ALWAYS_INLINE static inline ArtField* FindFieldByName( - Thread* self ATTRIBUTE_UNUSED, mirror::String* name, LengthPrefixedArray<ArtField>* fields) +ALWAYS_INLINE static inline ArtField* FindFieldByName(ObjPtr<mirror::String> name, + LengthPrefixedArray<ArtField>* fields) REQUIRES_SHARED(Locks::mutator_lock_) { if (fields == nullptr) { return nullptr; @@ -237,14 +240,15 @@ ALWAYS_INLINE static inline ArtField* FindFieldByName( return nullptr; } -ALWAYS_INLINE static inline mirror::Field* GetDeclaredField( - Thread* self, mirror::Class* c, mirror::String* name) +ALWAYS_INLINE static inline mirror::Field* GetDeclaredField(Thread* self, + ObjPtr<mirror::Class> c, + ObjPtr<mirror::String> name) REQUIRES_SHARED(Locks::mutator_lock_) { - ArtField* art_field = FindFieldByName(self, name, c->GetIFieldsPtr()); + ArtField* art_field = FindFieldByName(name, c->GetIFieldsPtr()); if (art_field != nullptr) { return mirror::Field::CreateFromArtField<kRuntimePointerSize>(self, art_field, true); } - art_field = FindFieldByName(self, name, c->GetSFieldsPtr()); + art_field = FindFieldByName(name, c->GetSFieldsPtr()); if (art_field != nullptr) { return mirror::Field::CreateFromArtField<kRuntimePointerSize>(self, art_field, true); } @@ -252,7 +256,7 @@ ALWAYS_INLINE static inline mirror::Field* GetDeclaredField( } static mirror::Field* GetPublicFieldRecursive( - Thread* self, mirror::Class* clazz, mirror::String* name) + Thread* self, ObjPtr<mirror::Class> clazz, ObjPtr<mirror::String> name) REQUIRES_SHARED(Locks::mutator_lock_) { DCHECK(clazz != nullptr); DCHECK(name != nullptr); @@ -302,7 +306,7 @@ static mirror::Field* GetPublicFieldRecursive( static jobject Class_getPublicFieldRecursive(JNIEnv* env, jobject javaThis, jstring name) { ScopedFastNativeObjectAccess soa(env); - auto* name_string = soa.Decode<mirror::String*>(name); + auto name_string = soa.Decode<mirror::String>(name); if (UNLIKELY(name_string == nullptr)) { ThrowNullPointerException("name == null"); return nullptr; @@ -313,16 +317,18 @@ static jobject Class_getPublicFieldRecursive(JNIEnv* env, jobject javaThis, jstr static jobject Class_getDeclaredField(JNIEnv* env, jobject javaThis, jstring name) { ScopedFastNativeObjectAccess soa(env); - auto* name_string = soa.Decode<mirror::String*>(name); - if (name_string == nullptr) { + StackHandleScope<3> hs(soa.Self()); + Handle<mirror::String> h_string = hs.NewHandle(soa.Decode<mirror::String>(name)); + if (h_string.Get() == nullptr) { ThrowNullPointerException("name == null"); return nullptr; } - auto* klass = DecodeClass(soa, javaThis); - mirror::Field* result = GetDeclaredField(soa.Self(), klass, name_string); - if (result == nullptr) { - std::string name_str = name_string->ToModifiedUtf8(); - if (name_str == "value" && klass->IsStringClass()) { + Handle<mirror::Class> h_klass = hs.NewHandle(DecodeClass(soa, javaThis)); + Handle<mirror::Field> result = + hs.NewHandle(GetDeclaredField(soa.Self(), h_klass.Get(), h_string.Get())); + if (result.Get() == nullptr) { + std::string name_str = h_string->ToModifiedUtf8(); + if (name_str == "value" && h_klass->IsStringClass()) { // We log the error for this specific case, as the user might just swallow the exception. // This helps diagnose crashes when applications rely on the String#value field being // there. @@ -333,11 +339,11 @@ static jobject Class_getDeclaredField(JNIEnv* env, jobject javaThis, jstring nam } // We may have a pending exception if we failed to resolve. if (!soa.Self()->IsExceptionPending()) { - ThrowNoSuchFieldException(DecodeClass(soa, javaThis), name_str.c_str()); + ThrowNoSuchFieldException(h_klass.Get(), name_str.c_str()); } return nullptr; } - return soa.AddLocalReference<jobject>(result); + return soa.AddLocalReference<jobject>(result.Get()); } static jobject Class_getDeclaredConstructorInternal( @@ -345,11 +351,11 @@ static jobject Class_getDeclaredConstructorInternal( ScopedFastNativeObjectAccess soa(env); DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize); DCHECK(!Runtime::Current()->IsActiveTransaction()); - mirror::Constructor* result = mirror::Class::GetDeclaredConstructorInternal<kRuntimePointerSize, - false>( + ObjPtr<mirror::Constructor> result = + mirror::Class::GetDeclaredConstructorInternal<kRuntimePointerSize, false>( soa.Self(), - DecodeClass(soa, javaThis), - soa.Decode<mirror::ObjectArray<mirror::Class>*>(args)); + DecodeClass(soa, javaThis).Decode(), + soa.Decode<mirror::ObjectArray<mirror::Class>>(args).Decode()); return soa.AddLocalReference<jobject>(result); } @@ -399,9 +405,9 @@ static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis, DCHECK(!Runtime::Current()->IsActiveTransaction()); mirror::Method* result = mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize, false>( soa.Self(), - DecodeClass(soa, javaThis), - soa.Decode<mirror::String*>(name), - soa.Decode<mirror::ObjectArray<mirror::Class>*>(args)); + DecodeClass(soa, javaThis).Decode(), + soa.Decode<mirror::String>(name).Decode(), + soa.Decode<mirror::ObjectArray<mirror::Class>>(args).Decode()); return soa.AddLocalReference<jobject>(result); } @@ -454,7 +460,7 @@ static jobject Class_getDeclaredAnnotation(JNIEnv* env, jobject javaThis, jclass if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { return nullptr; } - Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class*>(annotationClass))); + Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class>(annotationClass))); return soa.AddLocalReference<jobject>( annotations::GetAnnotationForClass(klass, annotation_class)); } @@ -465,10 +471,12 @@ static jobjectArray Class_getDeclaredAnnotations(JNIEnv* env, jobject javaThis) Handle<mirror::Class> klass(hs.NewHandle(DecodeClass(soa, javaThis))); if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { // Return an empty array instead of a null pointer. - mirror::Class* annotation_array_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); + ObjPtr<mirror::Class> annotation_array_class = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array); mirror::ObjectArray<mirror::Object>* empty_array = - mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0); + mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), + annotation_array_class.Decode(), + 0); return soa.AddLocalReference<jobjectArray>(empty_array); } return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForClass(klass)); @@ -520,8 +528,8 @@ static jobject Class_getEnclosingConstructorNative(JNIEnv* env, jobject javaThis } mirror::Object* method = annotations::GetEnclosingMethod(klass); if (method != nullptr) { - if (method->GetClass() == - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Constructor)) { + if (soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Constructor) == + method->GetClass()) { return soa.AddLocalReference<jobject>(method); } } @@ -537,8 +545,8 @@ static jobject Class_getEnclosingMethodNative(JNIEnv* env, jobject javaThis) { } mirror::Object* method = annotations::GetEnclosingMethod(klass); if (method != nullptr) { - if (method->GetClass() == - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Method)) { + if (soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Method) == + method->GetClass()) { return soa.AddLocalReference<jobject>(method); } } @@ -599,7 +607,7 @@ static jboolean Class_isDeclaredAnnotationPresent(JNIEnv* env, jobject javaThis, if (klass->IsProxyClass() || klass->GetDexCache() == nullptr) { return false; } - Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + Handle<mirror::Class> annotation_class(hs.NewHandle(soa.Decode<mirror::Class>(annotationType))); return annotations::IsClassAnnotationPresent(klass, annotation_class); } diff --git a/runtime/native/java_lang_DexCache.cc b/runtime/native/java_lang_DexCache.cc index f0140a303b..5efafe79fd 100644 --- a/runtime/native/java_lang_DexCache.cc +++ b/runtime/native/java_lang_DexCache.cc @@ -21,14 +21,14 @@ #include "mirror/class-inl.h" #include "mirror/dex_cache-inl.h" #include "mirror/object-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "well_known_classes.h" namespace art { static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) { ScopedFastNativeObjectAccess soa(env); - mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache); + ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); // Should only be called while holding the lock on the dex cache. DCHECK_EQ(dex_cache->GetLockOwnerThreadId(), soa.Self()->GetThreadId()); const DexFile* dex_file = dex_cache->GetDexFile(); @@ -51,14 +51,14 @@ static jobject DexCache_getDexNative(JNIEnv* env, jobject javaDexCache) { static jobject DexCache_getResolvedType(JNIEnv* env, jobject javaDexCache, jint type_index) { ScopedFastNativeObjectAccess soa(env); - mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache); + ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); return soa.AddLocalReference<jobject>(dex_cache->GetResolvedType(type_index)); } static jobject DexCache_getResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index) { ScopedFastNativeObjectAccess soa(env); - mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache); + ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(string_index), dex_cache->GetDexFile()->NumStringIds()); return soa.AddLocalReference<jobject>(dex_cache->GetResolvedString(string_index)); } @@ -66,17 +66,17 @@ static jobject DexCache_getResolvedString(JNIEnv* env, jobject javaDexCache, jin static void DexCache_setResolvedType(JNIEnv* env, jobject javaDexCache, jint type_index, jobject type) { ScopedFastNativeObjectAccess soa(env); - mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache); + ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(type_index), dex_cache->NumResolvedTypes()); - dex_cache->SetResolvedType(type_index, soa.Decode<mirror::Class*>(type)); + dex_cache->SetResolvedType(type_index, soa.Decode<mirror::Class>(type).Decode()); } static void DexCache_setResolvedString(JNIEnv* env, jobject javaDexCache, jint string_index, jobject string) { ScopedFastNativeObjectAccess soa(env); - mirror::DexCache* dex_cache = soa.Decode<mirror::DexCache*>(javaDexCache); + ObjPtr<mirror::DexCache> dex_cache = soa.Decode<mirror::DexCache>(javaDexCache); CHECK_LT(static_cast<size_t>(string_index), dex_cache->GetDexFile()->NumStringIds()); - dex_cache->SetResolvedString(string_index, soa.Decode<mirror::String*>(string)); + dex_cache->SetResolvedString(string_index, soa.Decode<mirror::String>(string).Decode()); } static JNINativeMethod gMethods[] = { diff --git a/runtime/native/java_lang_Object.cc b/runtime/native/java_lang_Object.cc index 2a36059a17..6493865c99 100644 --- a/runtime/native/java_lang_Object.cc +++ b/runtime/native/java_lang_Object.cc @@ -18,39 +18,35 @@ #include "jni_internal.h" #include "mirror/object-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" namespace art { static jobject Object_internalClone(JNIEnv* env, jobject java_this) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_this); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_this); return soa.AddLocalReference<jobject>(o->Clone(soa.Self())); } static void Object_notify(JNIEnv* env, jobject java_this) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_this); - o->Notify(soa.Self()); + soa.Decode<mirror::Object>(java_this)->Notify(soa.Self()); } static void Object_notifyAll(JNIEnv* env, jobject java_this) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_this); - o->NotifyAll(soa.Self()); + soa.Decode<mirror::Object>(java_this)->NotifyAll(soa.Self()); } static void Object_wait(JNIEnv* env, jobject java_this) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_this); - o->Wait(soa.Self()); + soa.Decode<mirror::Object>(java_this)->Wait(soa.Self()); } static void Object_waitJI(JNIEnv* env, jobject java_this, jlong ms, jint ns) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(java_this); - o->Wait(soa.Self(), ms, ns); + soa.Decode<mirror::Object>(java_this)->Wait(soa.Self(), ms, ns); } static JNINativeMethod gMethods[] = { diff --git a/runtime/native/java_lang_String.cc b/runtime/native/java_lang_String.cc index aa64b79994..b3a967d167 100644 --- a/runtime/native/java_lang_String.cc +++ b/runtime/native/java_lang_String.cc @@ -22,8 +22,8 @@ #include "mirror/object-inl.h" #include "mirror/string.h" #include "mirror/string-inl.h" -#include "scoped_fast_native_object_access.h" -#include "scoped_thread_state_change.h" +#include "scoped_fast_native_object_access-inl.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "verify_object-inl.h" @@ -31,7 +31,7 @@ namespace art { static jchar String_charAt(JNIEnv* env, jobject java_this, jint index) { ScopedFastNativeObjectAccess soa(env); - return soa.Decode<mirror::String*>(java_this)->CharAt(index); + return soa.Decode<mirror::String>(java_this)->CharAt(index); } static jint String_compareTo(JNIEnv* env, jobject java_this, jobject java_rhs) { @@ -40,7 +40,8 @@ static jint String_compareTo(JNIEnv* env, jobject java_this, jobject java_rhs) { ThrowNullPointerException("rhs == null"); return -1; } else { - return soa.Decode<mirror::String*>(java_this)->CompareTo(soa.Decode<mirror::String*>(java_rhs)); + return soa.Decode<mirror::String>(java_this)->CompareTo( + soa.Decode<mirror::String>(java_rhs).Decode()); } } @@ -51,8 +52,8 @@ static jstring String_concat(JNIEnv* env, jobject java_this, jobject java_string return nullptr; } StackHandleScope<2> hs(soa.Self()); - Handle<mirror::String> string_this(hs.NewHandle(soa.Decode<mirror::String*>(java_this))); - Handle<mirror::String> string_arg(hs.NewHandle(soa.Decode<mirror::String*>(java_string_arg))); + Handle<mirror::String> string_this(hs.NewHandle(soa.Decode<mirror::String>(java_this))); + Handle<mirror::String> string_arg(hs.NewHandle(soa.Decode<mirror::String>(java_string_arg))); int32_t length_this = string_this->GetLength(); int32_t length_arg = string_arg->GetLength(); if (length_arg > 0 && length_this > 0) { @@ -67,13 +68,13 @@ static jint String_fastIndexOf(JNIEnv* env, jobject java_this, jint ch, jint sta ScopedFastNativeObjectAccess soa(env); // This method does not handle supplementary characters. They're dealt with in managed code. DCHECK_LE(ch, 0xffff); - return soa.Decode<mirror::String*>(java_this)->FastIndexOf(ch, start); + return soa.Decode<mirror::String>(java_this)->FastIndexOf(ch, start); } static jstring String_fastSubstring(JNIEnv* env, jobject java_this, jint start, jint length) { ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::String> string_this(hs.NewHandle(soa.Decode<mirror::String*>(java_this))); + Handle<mirror::String> string_this(hs.NewHandle(soa.Decode<mirror::String>(java_this))); gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); mirror::String* result = mirror::String::AllocFromString<true>(soa.Self(), length, string_this, start, allocator_type); @@ -84,25 +85,24 @@ static void String_getCharsNoCheck(JNIEnv* env, jobject java_this, jint start, j jcharArray buffer, jint index) { ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::CharArray> char_array(hs.NewHandle(soa.Decode<mirror::CharArray*>(buffer))); - soa.Decode<mirror::String*>(java_this)->GetChars(start, end, char_array, index); + Handle<mirror::CharArray> char_array(hs.NewHandle(soa.Decode<mirror::CharArray>(buffer))); + soa.Decode<mirror::String>(java_this)->GetChars(start, end, char_array, index); } static jstring String_intern(JNIEnv* env, jobject java_this) { ScopedFastNativeObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_this); - mirror::String* result = s->Intern(); + ObjPtr<mirror::String> result = soa.Decode<mirror::String>(java_this)->Intern(); return soa.AddLocalReference<jstring>(result); } static void String_setCharAt(JNIEnv* env, jobject java_this, jint index, jchar c) { ScopedFastNativeObjectAccess soa(env); - soa.Decode<mirror::String*>(java_this)->SetCharAt(index, c); + soa.Decode<mirror::String>(java_this)->SetCharAt(index, c); } static jcharArray String_toCharArray(JNIEnv* env, jobject java_this) { ScopedFastNativeObjectAccess soa(env); - mirror::String* s = soa.Decode<mirror::String*>(java_this); + ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_this); return soa.AddLocalReference<jcharArray>(s->ToCharArray(soa.Self())); } diff --git a/runtime/native/java_lang_StringFactory.cc b/runtime/native/java_lang_StringFactory.cc index 5a219efc7b..119f2b87ba 100644 --- a/runtime/native/java_lang_StringFactory.cc +++ b/runtime/native/java_lang_StringFactory.cc @@ -20,8 +20,8 @@ #include "jni_internal.h" #include "mirror/object-inl.h" #include "mirror/string.h" -#include "scoped_fast_native_object_access.h" -#include "scoped_thread_state_change.h" +#include "scoped_fast_native_object_access-inl.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "ScopedPrimitiveArray.h" @@ -35,7 +35,7 @@ static jstring StringFactory_newStringFromBytes(JNIEnv* env, jclass, jbyteArray return nullptr; } StackHandleScope<1> hs(soa.Self()); - Handle<mirror::ByteArray> byte_array(hs.NewHandle(soa.Decode<mirror::ByteArray*>(java_data))); + Handle<mirror::ByteArray> byte_array(hs.NewHandle(soa.Decode<mirror::ByteArray>(java_data))); int32_t data_size = byte_array->GetLength(); if ((offset | byte_count) < 0 || byte_count > data_size - offset) { soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;", @@ -56,7 +56,7 @@ static jstring StringFactory_newStringFromChars(JNIEnv* env, jclass, jint offset DCHECK(java_data != nullptr); ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::CharArray> char_array(hs.NewHandle(soa.Decode<mirror::CharArray*>(java_data))); + Handle<mirror::CharArray> char_array(hs.NewHandle(soa.Decode<mirror::CharArray>(java_data))); gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); mirror::String* result = mirror::String::AllocFromCharArray<true>(soa.Self(), char_count, char_array, offset, @@ -71,7 +71,7 @@ static jstring StringFactory_newStringFromString(JNIEnv* env, jclass, jstring to return nullptr; } StackHandleScope<1> hs(soa.Self()); - Handle<mirror::String> string(hs.NewHandle(soa.Decode<mirror::String*>(to_copy))); + Handle<mirror::String> string(hs.NewHandle(soa.Decode<mirror::String>(to_copy))); gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator(); mirror::String* result = mirror::String::AllocFromString<true>(soa.Self(), string->GetLength(), string, 0, allocator_type); diff --git a/runtime/native/java_lang_System.cc b/runtime/native/java_lang_System.cc index 1b399aa251..8b9d0c7578 100644 --- a/runtime/native/java_lang_System.cc +++ b/runtime/native/java_lang_System.cc @@ -24,7 +24,7 @@ #include "mirror/class-inl.h" #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" namespace art { @@ -60,14 +60,14 @@ static void System_arraycopy(JNIEnv* env, jclass, jobject javaSrc, jint srcPos, } // Make sure source and destination are both arrays. - mirror::Object* srcObject = soa.Decode<mirror::Object*>(javaSrc); + ObjPtr<mirror::Object> srcObject = soa.Decode<mirror::Object>(javaSrc); if (UNLIKELY(!srcObject->IsArrayInstance())) { - ThrowArrayStoreException_NotAnArray("source", srcObject); + ThrowArrayStoreException_NotAnArray("source", srcObject.Decode()); return; } - mirror::Object* dstObject = soa.Decode<mirror::Object*>(javaDst); + ObjPtr<mirror::Object> dstObject = soa.Decode<mirror::Object>(javaDst); if (UNLIKELY(!dstObject->IsArrayInstance())) { - ThrowArrayStoreException_NotAnArray("destination", dstObject); + ThrowArrayStoreException_NotAnArray("destination", dstObject.Decode()); return; } mirror::Array* srcArray = srcObject->AsArray(); @@ -164,8 +164,8 @@ template <typename T, Primitive::Type kPrimType> inline void System_arraycopyTUnchecked(JNIEnv* env, jobject javaSrc, jint srcPos, jobject javaDst, jint dstPos, jint count) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* srcObject = soa.Decode<mirror::Object*>(javaSrc); - mirror::Object* dstObject = soa.Decode<mirror::Object*>(javaDst); + ObjPtr<mirror::Object> srcObject = soa.Decode<mirror::Object>(javaSrc); + ObjPtr<mirror::Object> dstObject = soa.Decode<mirror::Object>(javaDst); DCHECK(dstObject != nullptr); mirror::Array* srcArray = srcObject->AsArray(); mirror::Array* dstArray = dstObject->AsArray(); @@ -228,7 +228,7 @@ static jint System_identityHashCode(JNIEnv* env, jclass, jobject javaObject) { return 0; } ScopedFastNativeObjectAccess soa(env); - mirror::Object* o = soa.Decode<mirror::Object*>(javaObject); + ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(javaObject); return static_cast<jint>(o->IdentityHashCode()); } diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc index a742e812f7..063526150c 100644 --- a/runtime/native/java_lang_Thread.cc +++ b/runtime/native/java_lang_Thread.cc @@ -20,8 +20,8 @@ #include "jni_internal.h" #include "monitor.h" #include "mirror/object.h" -#include "scoped_fast_native_object_access.h" -#include "scoped_thread_state_change.h" +#include "scoped_fast_native_object_access-inl.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "thread.h" #include "thread_list.h" @@ -109,14 +109,14 @@ static jint Thread_nativeGetStatus(JNIEnv* env, jobject java_thread, jboolean ha static jboolean Thread_nativeHoldsLock(JNIEnv* env, jobject java_thread, jobject java_object) { ScopedObjectAccess soa(env); - mirror::Object* object = soa.Decode<mirror::Object*>(java_object); + ObjPtr<mirror::Object> object = soa.Decode<mirror::Object>(java_object); if (object == nullptr) { ThrowNullPointerException("object == null"); return JNI_FALSE; } MutexLock mu(soa.Self(), *Locks::thread_list_lock_); Thread* thread = Thread::FromManagedThread(soa, java_thread); - return thread->HoldsLock(object); + return thread->HoldsLock(object.Decode()); } static void Thread_nativeInterrupt(JNIEnv* env, jobject java_thread) { @@ -132,7 +132,7 @@ static void Thread_nativeSetName(JNIEnv* env, jobject peer, jstring java_name) { ScopedUtfChars name(env, java_name); { ScopedObjectAccess soa(env); - if (soa.Decode<mirror::Object*>(peer) == soa.Self()->GetPeer()) { + if (soa.Decode<mirror::Object>(peer) == soa.Self()->GetPeer()) { soa.Self()->SetThreadName(name.c_str()); return; } @@ -172,8 +172,8 @@ static void Thread_nativeSetPriority(JNIEnv* env, jobject java_thread, jint new_ static void Thread_sleep(JNIEnv* env, jclass, jobject java_lock, jlong ms, jint ns) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* lock = soa.Decode<mirror::Object*>(java_lock); - Monitor::Wait(Thread::Current(), lock, ms, ns, true, kSleeping); + ObjPtr<mirror::Object> lock = soa.Decode<mirror::Object>(java_lock); + Monitor::Wait(Thread::Current(), lock.Decode(), ms, ns, true, kSleeping); } /* diff --git a/runtime/native/java_lang_Throwable.cc b/runtime/native/java_lang_Throwable.cc index cb8a86918f..ff3e044c9b 100644 --- a/runtime/native/java_lang_Throwable.cc +++ b/runtime/native/java_lang_Throwable.cc @@ -17,7 +17,7 @@ #include "java_lang_Throwable.h" #include "jni_internal.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "thread.h" namespace art { diff --git a/runtime/native/java_lang_VMClassLoader.cc b/runtime/native/java_lang_VMClassLoader.cc index 6f735aa6df..0694c4dd72 100644 --- a/runtime/native/java_lang_VMClassLoader.cc +++ b/runtime/native/java_lang_VMClassLoader.cc @@ -20,7 +20,7 @@ #include "jni_internal.h" #include "mirror/class_loader.h" #include "mirror/object-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "ScopedUtfChars.h" #include "zip_archive.h" @@ -29,7 +29,7 @@ namespace art { static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoader, jstring javaName) { ScopedFastNativeObjectAccess soa(env); - mirror::ClassLoader* loader = soa.Decode<mirror::ClassLoader*>(javaLoader); + ObjPtr<mirror::ClassLoader> loader = soa.Decode<mirror::ClassLoader>(javaLoader); ScopedUtfChars name(env, javaName); if (name.c_str() == nullptr) { return nullptr; @@ -37,7 +37,10 @@ static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoa ClassLinker* cl = Runtime::Current()->GetClassLinker(); std::string descriptor(DotToDescriptor(name.c_str())); const size_t descriptor_hash = ComputeModifiedUtf8Hash(descriptor.c_str()); - mirror::Class* c = cl->LookupClass(soa.Self(), descriptor.c_str(), descriptor_hash, loader); + mirror::Class* c = cl->LookupClass(soa.Self(), + descriptor.c_str(), + descriptor_hash, + loader.Decode()); if (c != nullptr && c->IsResolved()) { return soa.AddLocalReference<jclass>(c); } diff --git a/runtime/native/java_lang_ref_FinalizerReference.cc b/runtime/native/java_lang_ref_FinalizerReference.cc index 0532c359a0..08bcc3880d 100644 --- a/runtime/native/java_lang_ref_FinalizerReference.cc +++ b/runtime/native/java_lang_ref_FinalizerReference.cc @@ -21,14 +21,15 @@ #include "jni_internal.h" #include "mirror/object-inl.h" #include "mirror/reference-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" namespace art { static jboolean FinalizerReference_makeCircularListIfUnenqueued(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); - mirror::FinalizerReference* const ref = soa.Decode<mirror::FinalizerReference*>(javaThis); - return Runtime::Current()->GetHeap()->GetReferenceProcessor()->MakeCircularListIfUnenqueued(ref); + ObjPtr<mirror::FinalizerReference> ref = soa.Decode<mirror::FinalizerReference>(javaThis); + return Runtime::Current()->GetHeap()->GetReferenceProcessor()->MakeCircularListIfUnenqueued( + ref.Decode()); } static JNINativeMethod gMethods[] = { diff --git a/runtime/native/java_lang_ref_Reference.cc b/runtime/native/java_lang_ref_Reference.cc index d2320591b1..9a088edc96 100644 --- a/runtime/native/java_lang_ref_Reference.cc +++ b/runtime/native/java_lang_ref_Reference.cc @@ -21,15 +21,15 @@ #include "jni_internal.h" #include "mirror/object-inl.h" #include "mirror/reference-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" namespace art { static jobject Reference_getReferent(JNIEnv* env, jobject javaThis) { ScopedFastNativeObjectAccess soa(env); - mirror::Reference* const ref = soa.Decode<mirror::Reference*>(javaThis); + ObjPtr<mirror::Reference> ref = soa.Decode<mirror::Reference>(javaThis); mirror::Object* const referent = - Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(soa.Self(), ref); + Runtime::Current()->GetHeap()->GetReferenceProcessor()->GetReferent(soa.Self(), ref.Decode()); return soa.AddLocalReference<jobject>(referent); } diff --git a/runtime/native/java_lang_reflect_Array.cc b/runtime/native/java_lang_reflect_Array.cc index beb953bd1b..3718ce83bf 100644 --- a/runtime/native/java_lang_reflect_Array.cc +++ b/runtime/native/java_lang_reflect_Array.cc @@ -22,7 +22,7 @@ #include "jni_internal.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "handle_scope-inl.h" namespace art { @@ -32,15 +32,15 @@ static jobject Array_createMultiArray( ScopedFastNativeObjectAccess soa(env); DCHECK(javaElementClass != nullptr); StackHandleScope<2> hs(soa.Self()); - Handle<mirror::Class> element_class(hs.NewHandle(soa.Decode<mirror::Class*>(javaElementClass))); + Handle<mirror::Class> element_class(hs.NewHandle(soa.Decode<mirror::Class>(javaElementClass))); DCHECK(element_class->IsClass()); DCHECK(javaDimArray != nullptr); - mirror::Object* dimensions_obj = soa.Decode<mirror::Object*>(javaDimArray); + ObjPtr<mirror::Object> dimensions_obj = soa.Decode<mirror::Object>(javaDimArray); DCHECK(dimensions_obj->IsArrayInstance()); DCHECK_EQ(dimensions_obj->GetClass()->GetComponentType()->GetPrimitiveType(), Primitive::kPrimInt); Handle<mirror::IntArray> dimensions_array( - hs.NewHandle(down_cast<mirror::IntArray*>(dimensions_obj))); + hs.NewHandle(down_cast<mirror::IntArray*>(dimensions_obj.Decode()))); mirror::Array* new_array = mirror::Array::CreateMultiArray(soa.Self(), element_class, dimensions_array); return soa.AddLocalReference<jobject>(new_array); @@ -53,7 +53,7 @@ static jobject Array_createObjectArray(JNIEnv* env, jclass, jclass javaElementCl ThrowNegativeArraySizeException(length); return nullptr; } - mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass); + mirror::Class* element_class = soa.Decode<mirror::Class>(javaElementClass).Decode(); Runtime* runtime = Runtime::Current(); ClassLinker* class_linker = runtime->GetClassLinker(); mirror::Class* array_class = class_linker->FindArrayClass(soa.Self(), &element_class); diff --git a/runtime/native/java_lang_reflect_Constructor.cc b/runtime/native/java_lang_reflect_Constructor.cc index 47c49d50ec..7de0147103 100644 --- a/runtime/native/java_lang_reflect_Constructor.cc +++ b/runtime/native/java_lang_reflect_Constructor.cc @@ -26,7 +26,7 @@ #include "mirror/method.h" #include "mirror/object-inl.h" #include "reflection.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "well_known_classes.h" namespace art { @@ -60,7 +60,7 @@ static jobjectArray Constructor_getExceptionTypes(JNIEnv* env, jobject javaMetho */ static jobject Constructor_newInstance0(JNIEnv* env, jobject javaMethod, jobjectArray javaArgs) { ScopedFastNativeObjectAccess soa(env); - mirror::Constructor* m = soa.Decode<mirror::Constructor*>(javaMethod); + ObjPtr<mirror::Constructor> m = soa.Decode<mirror::Constructor>(javaMethod); StackHandleScope<1> hs(soa.Self()); Handle<mirror::Class> c(hs.NewHandle(m->GetDeclaringClass())); if (UNLIKELY(c->IsAbstract())) { diff --git a/runtime/native/java_lang_reflect_Executable.cc b/runtime/native/java_lang_reflect_Executable.cc index f345c098e0..c7c80080ea 100644 --- a/runtime/native/java_lang_reflect_Executable.cc +++ b/runtime/native/java_lang_reflect_Executable.cc @@ -25,7 +25,7 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "reflection.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "well_known_classes.h" namespace art { @@ -35,10 +35,10 @@ static jobjectArray Executable_getDeclaredAnnotationsNative(JNIEnv* env, jobject ArtMethod* method = ArtMethod::FromReflectedMethod(soa, javaMethod); if (method->GetDeclaringClass()->IsProxyClass()) { // Return an empty array instead of a null pointer. - mirror::Class* annotation_array_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); - mirror::ObjectArray<mirror::Object>* empty_array = - mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0); + ObjPtr<mirror::Class> annotation_array_class = + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_annotation_Annotation__array); + ObjPtr<mirror::ObjectArray<mirror::Object>> empty_array = + mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class.Decode(), 0); return soa.AddLocalReference<jobjectArray>(empty_array); } return soa.AddLocalReference<jobjectArray>(annotations::GetAnnotationsForMethod(method)); @@ -53,7 +53,7 @@ static jobject Executable_getAnnotationNative(JNIEnv* env, if (method->IsProxyMethod()) { return nullptr; } else { - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType))); return soa.AddLocalReference<jobject>(annotations::GetAnnotationForMethod(method, klass)); } } @@ -84,7 +84,7 @@ static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) { Thread* self = soa.Self(); StackHandleScope<8> hs(self); - Handle<mirror::Method> executable = hs.NewHandle(soa.Decode<mirror::Method*>(javaMethod)); + Handle<mirror::Method> executable = hs.NewHandle(soa.Decode<mirror::Method>(javaMethod)); ArtMethod* art_method = executable.Get()->GetArtMethod(); if (art_method->GetDeclaringClass()->IsProxyClass()) { return nullptr; @@ -122,7 +122,7 @@ static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) { // Instantiate a Parameter[] to hold the result. Handle<mirror::Class> parameter_array_class = hs.NewHandle( - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Parameter__array)); + soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Parameter__array)); Handle<mirror::ObjectArray<mirror::Object>> parameter_array = hs.NewHandle( mirror::ObjectArray<mirror::Object>::Alloc(self, @@ -134,7 +134,7 @@ static jobjectArray Executable_getParameters0(JNIEnv* env, jobject javaMethod) { } Handle<mirror::Class> parameter_class = - hs.NewHandle(soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_reflect_Parameter)); + hs.NewHandle(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_reflect_Parameter)); ArtMethod* parameter_init = soa.DecodeMethod(WellKnownClasses::java_lang_reflect_Parameter_init); @@ -186,7 +186,7 @@ static jboolean Executable_isAnnotationPresentNative(JNIEnv* env, return false; } StackHandleScope<1> hs(soa.Self()); - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType))); return annotations::IsMethodAnnotationPresent(method, klass); } diff --git a/runtime/native/java_lang_reflect_Field.cc b/runtime/native/java_lang_reflect_Field.cc index dab510dc8c..2519225580 100644 --- a/runtime/native/java_lang_reflect_Field.cc +++ b/runtime/native/java_lang_reflect_Field.cc @@ -25,7 +25,7 @@ #include "mirror/class-inl.h" #include "mirror/field.h" #include "reflection-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "utils.h" namespace art { @@ -127,7 +127,7 @@ ALWAYS_INLINE inline static bool CheckReceiver(const ScopedFastNativeObjectAcces *class_or_rcvr = declaringClass; return true; } - *class_or_rcvr = soa.Decode<mirror::Object*>(j_rcvr); + *class_or_rcvr = soa.Decode<mirror::Object>(j_rcvr).Decode(); if (!VerifyObjectIsClass(MakeObjPtr(*class_or_rcvr), MakeObjPtr(declaringClass))) { DCHECK(soa.Self()->IsExceptionPending()); return false; @@ -137,7 +137,7 @@ ALWAYS_INLINE inline static bool CheckReceiver(const ScopedFastNativeObjectAcces static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) { ScopedFastNativeObjectAccess soa(env); - mirror::Field* f = soa.Decode<mirror::Field*>(javaField); + mirror::Field* f = soa.Decode<mirror::Field>(javaField).Decode(); mirror::Object* o = nullptr; if (!CheckReceiver(soa, javaObj, &f, &o)) { DCHECK(soa.Self()->IsExceptionPending()); @@ -163,7 +163,7 @@ template<Primitive::Type kPrimitiveType> ALWAYS_INLINE inline static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj) { ScopedFastNativeObjectAccess soa(env); - mirror::Field* f = soa.Decode<mirror::Field*>(javaField); + mirror::Field* f = soa.Decode<mirror::Field>(javaField).Decode(); mirror::Object* o = nullptr; if (!CheckReceiver(soa, javaObj, &f, &o)) { DCHECK(soa.Self()->IsExceptionPending()); @@ -307,7 +307,7 @@ ALWAYS_INLINE inline static void SetFieldValue(mirror::Object* o, mirror::Field* static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Field* f = soa.Decode<mirror::Field*>(javaField); + mirror::Field* f = soa.Decode<mirror::Field>(javaField).Decode(); // Check that the receiver is non-null and an instance of the field's declaring class. mirror::Object* o = nullptr; if (!CheckReceiver(soa, javaObj, &f, &o)) { @@ -325,9 +325,9 @@ static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject j } // We now don't expect suspension unless an exception is thrown. // Unbox the value, if necessary. - mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue); + ObjPtr<mirror::Object> boxed_value = soa.Decode<mirror::Object>(javaValue); JValue unboxed_value; - if (!UnboxPrimitiveForField(MakeObjPtr(boxed_value), + if (!UnboxPrimitiveForField(boxed_value, MakeObjPtr(field_type), f->GetArtField(), &unboxed_value)) { @@ -346,7 +346,7 @@ template<Primitive::Type kPrimitiveType> static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, const JValue& new_value) { ScopedFastNativeObjectAccess soa(env); - mirror::Field* f = soa.Decode<mirror::Field*>(javaField); + mirror::Field* f = soa.Decode<mirror::Field>(javaField).Decode(); mirror::Object* o = nullptr; if (!CheckReceiver(soa, javaObj, &f, &o)) { return; @@ -426,21 +426,22 @@ static void Field_setShort(JNIEnv* env, jobject javaField, jobject javaObj, jsho static jobject Field_getAnnotationNative(JNIEnv* env, jobject javaField, jclass annotationType) { ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField(); + ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField(); if (field->GetDeclaringClass()->IsProxyClass()) { return nullptr; } - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType))); return soa.AddLocalReference<jobject>(annotations::GetAnnotationForField(field, klass)); } static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) { ScopedFastNativeObjectAccess soa(env); - ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField(); + ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField(); if (field->GetDeclaringClass()->IsProxyClass()) { // Return an empty array instead of a null pointer. mirror::Class* annotation_array_class = - soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_annotation_Annotation__array); + soa.Decode<mirror::Class>( + WellKnownClasses::java_lang_annotation_Annotation__array).Decode(); mirror::ObjectArray<mirror::Object>* empty_array = mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), annotation_array_class, 0); return soa.AddLocalReference<jobjectArray>(empty_array); @@ -450,7 +451,7 @@ static jobjectArray Field_getDeclaredAnnotations(JNIEnv* env, jobject javaField) static jobjectArray Field_getSignatureAnnotation(JNIEnv* env, jobject javaField) { ScopedFastNativeObjectAccess soa(env); - ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField(); + ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField(); if (field->GetDeclaringClass()->IsProxyClass()) { return nullptr; } @@ -461,11 +462,11 @@ static jboolean Field_isAnnotationPresentNative(JNIEnv* env, jobject javaField, jclass annotationType) { ScopedFastNativeObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - ArtField* field = soa.Decode<mirror::Field*>(javaField)->GetArtField(); + ArtField* field = soa.Decode<mirror::Field>(javaField)->GetArtField(); if (field->GetDeclaringClass()->IsProxyClass()) { return false; } - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType))); return annotations::IsFieldAnnotationPresent(field, klass); } diff --git a/runtime/native/java_lang_reflect_Method.cc b/runtime/native/java_lang_reflect_Method.cc index b8efb14903..b5f2f7ca90 100644 --- a/runtime/native/java_lang_reflect_Method.cc +++ b/runtime/native/java_lang_reflect_Method.cc @@ -26,7 +26,7 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "reflection.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "well_known_classes.h" namespace art { diff --git a/runtime/native/java_lang_reflect_Parameter.cc b/runtime/native/java_lang_reflect_Parameter.cc index c2a803c3cd..6060b8a2f6 100644 --- a/runtime/native/java_lang_reflect_Parameter.cc +++ b/runtime/native/java_lang_reflect_Parameter.cc @@ -21,7 +21,7 @@ #include "dex_file-inl.h" #include "dex_file_annotations.h" #include "jni_internal.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "utils.h" namespace art { @@ -53,7 +53,7 @@ static jobject Parameter_getAnnotationNative(JNIEnv* env, } StackHandleScope<1> hs(soa.Self()); - Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class*>(annotationType))); + Handle<mirror::Class> klass(hs.NewHandle(soa.Decode<mirror::Class>(annotationType))); return soa.AddLocalReference<jobject>( annotations::GetAnnotationForMethodParameter(method, parameterIndex, klass)); } diff --git a/runtime/native/java_lang_reflect_Proxy.cc b/runtime/native/java_lang_reflect_Proxy.cc index 4a6ab404f2..ece0338c93 100644 --- a/runtime/native/java_lang_reflect_Proxy.cc +++ b/runtime/native/java_lang_reflect_Proxy.cc @@ -21,7 +21,7 @@ #include "mirror/class_loader.h" #include "mirror/object_array.h" #include "mirror/string.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "verify_object-inl.h" namespace art { diff --git a/runtime/native/libcore_util_CharsetUtils.cc b/runtime/native/libcore_util_CharsetUtils.cc index 64d56f6b26..2590452678 100644 --- a/runtime/native/libcore_util_CharsetUtils.cc +++ b/runtime/native/libcore_util_CharsetUtils.cc @@ -18,7 +18,7 @@ #include "mirror/string.h" #include "mirror/string-inl.h" #include "native/libcore_util_CharsetUtils.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "ScopedPrimitiveArray.h" #include "unicode/utf16.h" @@ -154,7 +154,7 @@ static jbyteArray charsToBytes(JNIEnv* env, jstring java_string, jint offset, ji jchar maxValidChar) { ScopedObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::String> string(hs.NewHandle(soa.Decode<mirror::String*>(java_string))); + Handle<mirror::String> string(hs.NewHandle(soa.Decode<mirror::String>(java_string))); if (string.Get() == nullptr) { return nullptr; } @@ -191,7 +191,7 @@ static jbyteArray CharsetUtils_toUtf8Bytes(JNIEnv* env, jclass, jstring java_str jint length) { ScopedObjectAccess soa(env); StackHandleScope<1> hs(soa.Self()); - Handle<mirror::String> string(hs.NewHandle(soa.Decode<mirror::String*>(java_string))); + Handle<mirror::String> string(hs.NewHandle(soa.Decode<mirror::String>(java_string))); if (string.Get() == nullptr) { return nullptr; } diff --git a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc index 0ab29799a0..5356498fc8 100644 --- a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc +++ b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmServer.cc @@ -19,7 +19,7 @@ #include "base/logging.h" #include "debugger.h" #include "jni_internal.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "ScopedPrimitiveArray.h" namespace art { diff --git a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc index 9ed0e7eacc..ca17c26c95 100644 --- a/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc +++ b/runtime/native/org_apache_harmony_dalvik_ddmc_DdmVmInternal.cc @@ -20,7 +20,7 @@ #include "base/mutex.h" #include "debugger.h" #include "jni_internal.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include "ScopedLocalRef.h" #include "ScopedPrimitiveArray.h" #include "thread_list.h" diff --git a/runtime/native/scoped_fast_native_object_access-inl.h b/runtime/native/scoped_fast_native_object_access-inl.h new file mode 100644 index 0000000000..1d73813fcd --- /dev/null +++ b/runtime/native/scoped_fast_native_object_access-inl.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_INL_H_ +#define ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_INL_H_ + +#include "scoped_fast_native_object_access.h" + +#include "art_method-inl.h" +#include "scoped_thread_state_change-inl.h" + +namespace art { + +inline ScopedFastNativeObjectAccess::ScopedFastNativeObjectAccess(JNIEnv* env) + : ScopedObjectAccessAlreadyRunnable(env) { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK((*Self()->GetManagedStack()->GetTopQuickFrame())->IsFastNative()); + // Don't work with raw objects in non-runnable states. + DCHECK_EQ(Self()->GetState(), kRunnable); +} + +} // namespace art + +#endif // ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_INL_H_ diff --git a/runtime/native/scoped_fast_native_object_access.h b/runtime/native/scoped_fast_native_object_access.h index c4a33dfd14..6a9365d517 100644 --- a/runtime/native/scoped_fast_native_object_access.h +++ b/runtime/native/scoped_fast_native_object_access.h @@ -17,7 +17,8 @@ #ifndef ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_ #define ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_ -#include "art_method-inl.h" +#include <jni.h> + #include "scoped_thread_state_change.h" namespace art { @@ -26,18 +27,11 @@ namespace art { // JNI methods. class ScopedFastNativeObjectAccess : public ScopedObjectAccessAlreadyRunnable { public: - explicit ScopedFastNativeObjectAccess(JNIEnv* env) + ALWAYS_INLINE explicit ScopedFastNativeObjectAccess(JNIEnv* env) REQUIRES(!Locks::thread_suspend_count_lock_) - SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE - : ScopedObjectAccessAlreadyRunnable(env) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK((*Self()->GetManagedStack()->GetTopQuickFrame())->IsFastNative()); - // Don't work with raw objects in non-runnable states. - DCHECK_EQ(Self()->GetState(), kRunnable); - } - - ~ScopedFastNativeObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE { - } + SHARED_LOCK_FUNCTION(Locks::mutator_lock_); + + ALWAYS_INLINE ~ScopedFastNativeObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) {} private: DISALLOW_COPY_AND_ASSIGN(ScopedFastNativeObjectAccess); diff --git a/runtime/native/sun_misc_Unsafe.cc b/runtime/native/sun_misc_Unsafe.cc index 472340cee7..2fae3cc8e7 100644 --- a/runtime/native/sun_misc_Unsafe.cc +++ b/runtime/native/sun_misc_Unsafe.cc @@ -21,7 +21,7 @@ #include "mirror/array.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" -#include "scoped_fast_native_object_access.h" +#include "scoped_fast_native_object_access-inl.h" #include <unistd.h> #include <stdlib.h> @@ -33,61 +33,64 @@ namespace art { static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint expectedValue, jint newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); // JNI must use non transactional mode. bool success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset), - expectedValue, newValue); + expectedValue, + newValue); return success ? JNI_TRUE : JNI_FALSE; } static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong expectedValue, jlong newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); // JNI must use non transactional mode. bool success = obj->CasFieldStrongSequentiallyConsistent64<false>(MemberOffset(offset), - expectedValue, newValue); + expectedValue, + newValue); return success ? JNI_TRUE : JNI_FALSE; } static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaExpectedValue, jobject javaNewValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue); - mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + ObjPtr<mirror::Object> expectedValue = soa.Decode<mirror::Object>(javaExpectedValue); + ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue); // JNI must use non transactional mode. if (kUseReadBarrier) { // Need to make sure the reference stored in the field is a to-space one before attempting the // CAS or the CAS could fail incorrectly. mirror::HeapReference<mirror::Object>* field_addr = reinterpret_cast<mirror::HeapReference<mirror::Object>*>( - reinterpret_cast<uint8_t*>(obj) + static_cast<size_t>(offset)); + reinterpret_cast<uint8_t*>(obj.Decode()) + static_cast<size_t>(offset)); ReadBarrier::Barrier<mirror::Object, kWithReadBarrier, /*kAlwaysUpdateField*/true>( - obj, + obj.Decode(), MemberOffset(offset), field_addr); } bool success = obj->CasFieldStrongSequentiallyConsistentObject<false>(MemberOffset(offset), - expectedValue, newValue); + expectedValue.Decode(), + newValue.Decode()); return success ? JNI_TRUE : JNI_FALSE; } static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); return obj->GetField32(MemberOffset(offset)); } static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); return obj->GetField32Volatile(MemberOffset(offset)); } static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); // JNI must use non transactional mode. obj->SetField32<false>(MemberOffset(offset), newValue); } @@ -95,7 +98,7 @@ static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, j static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); // JNI must use non transactional mode. obj->SetField32Volatile<false>(MemberOffset(offset), newValue); } @@ -103,7 +106,7 @@ static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong o static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); QuasiAtomic::ThreadFenceRelease(); // JNI must use non transactional mode. obj->SetField32<false>(MemberOffset(offset), newValue); @@ -111,19 +114,19 @@ static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong of static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); return obj->GetField64(MemberOffset(offset)); } static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); return obj->GetField64Volatile(MemberOffset(offset)); } static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); // JNI must use non transactional mode. obj->SetField64<false>(MemberOffset(offset), newValue); } @@ -131,7 +134,7 @@ static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); // JNI must use non transactional mode. obj->SetField64Volatile<false>(MemberOffset(offset), newValue); } @@ -139,7 +142,7 @@ static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); QuasiAtomic::ThreadFenceRelease(); // JNI must use non transactional mode. obj->SetField64<false>(MemberOffset(offset), newValue); @@ -147,56 +150,56 @@ static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong o static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - mirror::Object* value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset)); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + ObjPtr<mirror::Object> value = obj->GetFieldObjectVolatile<mirror::Object>(MemberOffset(offset)); return soa.AddLocalReference<jobject>(value); } static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - mirror::Object* value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset)); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + ObjPtr<mirror::Object> value = obj->GetFieldObject<mirror::Object>(MemberOffset(offset)); return soa.AddLocalReference<jobject>(value); } static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaNewValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue); // JNI must use non transactional mode. - obj->SetFieldObject<false>(MemberOffset(offset), newValue); + obj->SetFieldObject<false>(MemberOffset(offset), newValue.Decode()); } static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaNewValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue); // JNI must use non transactional mode. - obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue); + obj->SetFieldObjectVolatile<false>(MemberOffset(offset), newValue.Decode()); } static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaNewValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + ObjPtr<mirror::Object> newValue = soa.Decode<mirror::Object>(javaNewValue); QuasiAtomic::ThreadFenceRelease(); // JNI must use non transactional mode. - obj->SetFieldObject<false>(MemberOffset(offset), newValue); + obj->SetFieldObject<false>(MemberOffset(offset), newValue.Decode()); } static jint Unsafe_getArrayBaseOffsetForComponentType(JNIEnv* env, jclass, jobject component_class) { ScopedFastNativeObjectAccess soa(env); - mirror::Class* component = soa.Decode<mirror::Class*>(component_class); + ObjPtr<mirror::Class> component = soa.Decode<mirror::Class>(component_class); Primitive::Type primitive_type = component->GetPrimitiveType(); return mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value(); } static jint Unsafe_getArrayIndexScaleForComponentType(JNIEnv* env, jclass, jobject component_class) { ScopedFastNativeObjectAccess soa(env); - mirror::Class* component = soa.Decode<mirror::Class*>(component_class); + ObjPtr<mirror::Class> component = soa.Decode<mirror::Class>(component_class); Primitive::Type primitive_type = component->GetPrimitiveType(); return Primitive::ComponentSize(primitive_type); } @@ -289,16 +292,16 @@ static void Unsafe_putDoubleJD(JNIEnv* env ATTRIBUTE_UNUSED, jobject, jlong addr static void Unsafe_copyMemory(JNIEnv *env, jobject unsafe ATTRIBUTE_UNUSED, jlong src, jlong dst, jlong size) { - if (size == 0) { - return; - } - // size is nonnegative and fits into size_t - if (size < 0 || size != (jlong)(size_t) size) { - ScopedFastNativeObjectAccess soa(env); - ThrowIllegalAccessException("wrong number of bytes"); - } - size_t sz = (size_t)size; - memcpy(reinterpret_cast<void *>(dst), reinterpret_cast<void *>(src), sz); + if (size == 0) { + return; + } + // size is nonnegative and fits into size_t + if (size < 0 || size != (jlong)(size_t) size) { + ScopedFastNativeObjectAccess soa(env); + ThrowIllegalAccessException("wrong number of bytes"); + } + size_t sz = (size_t)size; + memcpy(reinterpret_cast<void *>(dst), reinterpret_cast<void *>(src), sz); } template<typename T> @@ -306,12 +309,12 @@ static void copyToArray(jlong srcAddr, mirror::PrimitiveArray<T>* array, size_t array_offset, size_t size) REQUIRES_SHARED(Locks::mutator_lock_) { - const T* src = reinterpret_cast<T*>(srcAddr); - size_t sz = size / sizeof(T); - size_t of = array_offset / sizeof(T); - for (size_t i = 0; i < sz; ++i) { - array->Set(i + of, *(src + i)); - } + const T* src = reinterpret_cast<T*>(srcAddr); + size_t sz = size / sizeof(T); + size_t of = array_offset / sizeof(T); + for (size_t i = 0; i < sz; ++i) { + array->Set(i + of, *(src + i)); + } } template<typename T> @@ -319,12 +322,12 @@ static void copyFromArray(jlong dstAddr, mirror::PrimitiveArray<T>* array, size_t array_offset, size_t size) REQUIRES_SHARED(Locks::mutator_lock_) { - T* dst = reinterpret_cast<T*>(dstAddr); - size_t sz = size / sizeof(T); - size_t of = array_offset / sizeof(T); - for (size_t i = 0; i < sz; ++i) { - *(dst + i) = array->Get(i + of); - } + T* dst = reinterpret_cast<T*>(dstAddr); + size_t sz = size / sizeof(T); + size_t of = array_offset / sizeof(T); + for (size_t i = 0; i < sz; ++i) { + *(dst + i) = array->Get(i + of); + } } static void Unsafe_copyMemoryToPrimitiveArray(JNIEnv *env, @@ -333,29 +336,29 @@ static void Unsafe_copyMemoryToPrimitiveArray(JNIEnv *env, jobject dstObj, jlong dstOffset, jlong size) { - ScopedObjectAccess soa(env); - if (size == 0) { - return; - } - // size is nonnegative and fits into size_t - if (size < 0 || size != (jlong)(size_t) size) { - ThrowIllegalAccessException("wrong number of bytes"); - } - size_t sz = (size_t)size; - size_t dst_offset = (size_t)dstOffset; - mirror::Object* dst = soa.Decode<mirror::Object*>(dstObj); - mirror::Class* component_type = dst->GetClass()->GetComponentType(); - if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) { - copyToArray(srcAddr, dst->AsByteSizedArray(), dst_offset, sz); - } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) { - copyToArray(srcAddr, dst->AsShortSizedArray(), dst_offset, sz); - } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) { - copyToArray(srcAddr, dst->AsIntArray(), dst_offset, sz); - } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) { - copyToArray(srcAddr, dst->AsLongArray(), dst_offset, sz); - } else { - ThrowIllegalAccessException("not a primitive array"); - } + ScopedObjectAccess soa(env); + if (size == 0) { + return; + } + // size is nonnegative and fits into size_t + if (size < 0 || size != (jlong)(size_t) size) { + ThrowIllegalAccessException("wrong number of bytes"); + } + size_t sz = (size_t)size; + size_t dst_offset = (size_t)dstOffset; + ObjPtr<mirror::Object> dst = soa.Decode<mirror::Object>(dstObj); + mirror::Class* component_type = dst->GetClass()->GetComponentType(); + if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) { + copyToArray(srcAddr, dst->AsByteSizedArray(), dst_offset, sz); + } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) { + copyToArray(srcAddr, dst->AsShortSizedArray(), dst_offset, sz); + } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) { + copyToArray(srcAddr, dst->AsIntArray(), dst_offset, sz); + } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) { + copyToArray(srcAddr, dst->AsLongArray(), dst_offset, sz); + } else { + ThrowIllegalAccessException("not a primitive array"); + } } static void Unsafe_copyMemoryFromPrimitiveArray(JNIEnv *env, @@ -364,85 +367,85 @@ static void Unsafe_copyMemoryFromPrimitiveArray(JNIEnv *env, jlong srcOffset, jlong dstAddr, jlong size) { - ScopedObjectAccess soa(env); - if (size == 0) { - return; - } - // size is nonnegative and fits into size_t - if (size < 0 || size != (jlong)(size_t) size) { - ThrowIllegalAccessException("wrong number of bytes"); - } - size_t sz = (size_t)size; - size_t src_offset = (size_t)srcOffset; - mirror::Object* src = soa.Decode<mirror::Object*>(srcObj); - mirror::Class* component_type = src->GetClass()->GetComponentType(); - if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) { - copyFromArray(dstAddr, src->AsByteSizedArray(), src_offset, sz); - } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) { - copyFromArray(dstAddr, src->AsShortSizedArray(), src_offset, sz); - } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) { - copyFromArray(dstAddr, src->AsIntArray(), src_offset, sz); - } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) { - copyFromArray(dstAddr, src->AsLongArray(), src_offset, sz); - } else { - ThrowIllegalAccessException("not a primitive array"); - } + ScopedObjectAccess soa(env); + if (size == 0) { + return; + } + // size is nonnegative and fits into size_t + if (size < 0 || size != (jlong)(size_t) size) { + ThrowIllegalAccessException("wrong number of bytes"); + } + size_t sz = (size_t)size; + size_t src_offset = (size_t)srcOffset; + ObjPtr<mirror::Object> src = soa.Decode<mirror::Object>(srcObj); + mirror::Class* component_type = src->GetClass()->GetComponentType(); + if (component_type->IsPrimitiveByte() || component_type->IsPrimitiveBoolean()) { + copyFromArray(dstAddr, src->AsByteSizedArray(), src_offset, sz); + } else if (component_type->IsPrimitiveShort() || component_type->IsPrimitiveChar()) { + copyFromArray(dstAddr, src->AsShortSizedArray(), src_offset, sz); + } else if (component_type->IsPrimitiveInt() || component_type->IsPrimitiveFloat()) { + copyFromArray(dstAddr, src->AsIntArray(), src_offset, sz); + } else if (component_type->IsPrimitiveLong() || component_type->IsPrimitiveDouble()) { + copyFromArray(dstAddr, src->AsLongArray(), src_offset, sz); + } else { + ThrowIllegalAccessException("not a primitive array"); + } } static jboolean Unsafe_getBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - return obj->GetFieldBoolean(MemberOffset(offset)); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + return obj->GetFieldBoolean(MemberOffset(offset)); } static void Unsafe_putBoolean(JNIEnv* env, jobject, jobject javaObj, jlong offset, jboolean newValue) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - // JNI must use non transactional mode (SetField8 is non-transactional). - obj->SetFieldBoolean<false>(MemberOffset(offset), newValue); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + // JNI must use non transactional mode (SetField8 is non-transactional). + obj->SetFieldBoolean<false>(MemberOffset(offset), newValue); } static jbyte Unsafe_getByte(JNIEnv* env, jobject, jobject javaObj, jlong offset) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - return obj->GetFieldByte(MemberOffset(offset)); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + return obj->GetFieldByte(MemberOffset(offset)); } static void Unsafe_putByte(JNIEnv* env, jobject, jobject javaObj, jlong offset, jbyte newValue) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - // JNI must use non transactional mode. - obj->SetFieldByte<false>(MemberOffset(offset), newValue); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + // JNI must use non transactional mode. + obj->SetFieldByte<false>(MemberOffset(offset), newValue); } static jchar Unsafe_getChar(JNIEnv* env, jobject, jobject javaObj, jlong offset) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - return obj->GetFieldChar(MemberOffset(offset)); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + return obj->GetFieldChar(MemberOffset(offset)); } static void Unsafe_putChar(JNIEnv* env, jobject, jobject javaObj, jlong offset, jchar newValue) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - // JNI must use non transactional mode. - obj->SetFieldChar<false>(MemberOffset(offset), newValue); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + // JNI must use non transactional mode. + obj->SetFieldChar<false>(MemberOffset(offset), newValue); } static jshort Unsafe_getShort(JNIEnv* env, jobject, jobject javaObj, jlong offset) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - return obj->GetFieldShort(MemberOffset(offset)); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + return obj->GetFieldShort(MemberOffset(offset)); } static void Unsafe_putShort(JNIEnv* env, jobject, jobject javaObj, jlong offset, jshort newValue) { - ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); - // JNI must use non transactional mode. - obj->SetFieldShort<false>(MemberOffset(offset), newValue); + ScopedFastNativeObjectAccess soa(env); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); + // JNI must use non transactional mode. + obj->SetFieldShort<false>(MemberOffset(offset), newValue); } static jfloat Unsafe_getFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); union {int32_t val; jfloat converted;} conv; conv.val = obj->GetField32(MemberOffset(offset)); return conv.converted; @@ -450,7 +453,7 @@ static jfloat Unsafe_getFloat(JNIEnv* env, jobject, jobject javaObj, jlong offse static void Unsafe_putFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset, jfloat newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); union {int32_t converted; jfloat val;} conv; conv.val = newValue; // JNI must use non transactional mode. @@ -459,7 +462,7 @@ static void Unsafe_putFloat(JNIEnv* env, jobject, jobject javaObj, jlong offset, static jdouble Unsafe_getDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); union {int64_t val; jdouble converted;} conv; conv.val = obj->GetField64(MemberOffset(offset)); return conv.converted; @@ -467,7 +470,7 @@ static jdouble Unsafe_getDouble(JNIEnv* env, jobject, jobject javaObj, jlong off static void Unsafe_putDouble(JNIEnv* env, jobject, jobject javaObj, jlong offset, jdouble newValue) { ScopedFastNativeObjectAccess soa(env); - mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj); + ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(javaObj); union {int64_t converted; jdouble val;} conv; conv.val = newValue; // JNI must use non transactional mode. diff --git a/runtime/native_bridge_art_interface.cc b/runtime/native_bridge_art_interface.cc index 155c008e85..059dc5adcb 100644 --- a/runtime/native_bridge_art_interface.cc +++ b/runtime/native_bridge_art_interface.cc @@ -26,7 +26,7 @@ #include "base/macros.h" #include "dex_file-inl.h" #include "mirror/class-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "sigchain.h" namespace art { @@ -43,7 +43,7 @@ static uint32_t GetNativeMethodCount(JNIEnv* env, jclass clazz) { } ScopedObjectAccess soa(env); - mirror::Class* c = soa.Decode<mirror::Class*>(clazz); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(clazz); uint32_t native_method_count = 0; for (auto& m : c->GetMethods(kRuntimePointerSize)) { @@ -58,7 +58,7 @@ static uint32_t GetNativeMethods(JNIEnv* env, jclass clazz, JNINativeMethod* met return 0; } ScopedObjectAccess soa(env); - mirror::Class* c = soa.Decode<mirror::Class*>(clazz); + ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(clazz); uint32_t count = 0; for (auto& m : c->GetMethods(kRuntimePointerSize)) { diff --git a/runtime/oat_file_assistant.cc b/runtime/oat_file_assistant.cc index 415f991b4f..ff00451343 100644 --- a/runtime/oat_file_assistant.cc +++ b/runtime/oat_file_assistant.cc @@ -27,7 +27,7 @@ #include "oat.h" #include "os.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "utils.h" namespace art { diff --git a/runtime/oat_file_assistant_test.cc b/runtime/oat_file_assistant_test.cc index 6ec5e55745..d18e9464e6 100644 --- a/runtime/oat_file_assistant_test.cc +++ b/runtime/oat_file_assistant_test.cc @@ -33,7 +33,7 @@ #include "oat_file_assistant.h" #include "oat_file_manager.h" #include "os.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc index 6d4b2f6aab..acad2a941b 100644 --- a/runtime/oat_file_manager.cc +++ b/runtime/oat_file_manager.cc @@ -30,7 +30,7 @@ #include "handle_scope-inl.h" #include "mirror/class_loader.h" #include "oat_file_assistant.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "thread_list.h" @@ -294,8 +294,8 @@ static bool GetDexFilesFromClassLoader( } // Unsupported class-loader? - if (class_loader->GetClass() != - soa.Decode<mirror::Class*>(WellKnownClasses::dalvik_system_PathClassLoader)) { + if (soa.Decode<mirror::Class>(WellKnownClasses::dalvik_system_PathClassLoader) != + class_loader->GetClass()) { VLOG(class_linker) << "Unsupported class-loader " << PrettyClass(class_loader->GetClass()); return false; } @@ -338,10 +338,10 @@ static void GetDexFilesFromDexElementsArray( ArtField* const cookie_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexFile_cookie); ArtField* const dex_file_field = soa.DecodeField(WellKnownClasses::dalvik_system_DexPathList__Element_dexFile); - const mirror::Class* const element_class = soa.Decode<mirror::Class*>( + ObjPtr<mirror::Class> const element_class = soa.Decode<mirror::Class>( WellKnownClasses::dalvik_system_DexPathList__Element); - const mirror::Class* const dexfile_class = soa.Decode<mirror::Class*>( - WellKnownClasses::dalvik_system_DexFile); + ObjPtr<mirror::Class> const dexfile_class = soa.Decode<mirror::Class>( + WellKnownClasses::dalvik_system_DexFile); // Collect all the dex files. auto GetDexFilesFn = [&] (const DexFile* cp_dex_file) @@ -361,9 +361,9 @@ static void GetDexFilesFromDexElementsArray( // We support this being dalvik.system.DexPathList$Element and dalvik.system.DexFile. mirror::Object* dex_file; - if (element->GetClass() == element_class) { + if (element_class == element->GetClass()) { dex_file = dex_file_field->GetObject(element); - } else if (element->GetClass() == dexfile_class) { + } else if (dexfile_class == element->GetClass()) { dex_file = element; } else { LOG(WARNING) << "Unsupported element in dex_elements: " << PrettyClass(element->GetClass()); @@ -442,9 +442,9 @@ bool OatFileManager::HasCollisions(const OatFile* oat_file, ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(Thread::Current()); Handle<mirror::ClassLoader> h_class_loader = - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader)); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader)); Handle<mirror::ObjectArray<mirror::Object>> h_dex_elements = - hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Object>*>(dex_elements)); + hs.NewHandle(soa.Decode<mirror::ObjectArray<mirror::Object>>(dex_elements)); if (h_class_loader.Get() != nullptr && GetDexFilesFromClassLoader(soa, h_class_loader.Get(), &queue)) { class_loader_ok = true; @@ -638,7 +638,7 @@ std::vector<std::unique_ptr<const DexFile>> OatFileManager::OpenDexFilesFromOat( ScopedObjectAccess soa(self); StackHandleScope<1> hs(self); Handle<mirror::ClassLoader> h_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader))); // Can not load app image without class loader. if (h_loader.Get() != nullptr) { std::string temp_error_msg; diff --git a/runtime/oat_file_test.cc b/runtime/oat_file_test.cc index a88553ca7b..b416b9dbad 100644 --- a/runtime/oat_file_test.cc +++ b/runtime/oat_file_test.cc @@ -21,7 +21,7 @@ #include <gtest/gtest.h> #include "common_runtime_test.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { diff --git a/runtime/oat_quick_method_header.cc b/runtime/oat_quick_method_header.cc index 0ab2bfe80e..a68d9f8811 100644 --- a/runtime/oat_quick_method_header.cc +++ b/runtime/oat_quick_method_header.cc @@ -17,7 +17,7 @@ #include "oat_quick_method_header.h" #include "art_method.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { diff --git a/runtime/obj_ptr-inl.h b/runtime/obj_ptr-inl.h index 3dfcf9e2cf..1c698b5c4d 100644 --- a/runtime/obj_ptr-inl.h +++ b/runtime/obj_ptr-inl.h @@ -41,6 +41,7 @@ inline void ObjPtr<MirrorType, kPoison>::AssertValid() const { template<class MirrorType, bool kPoison> inline uintptr_t ObjPtr<MirrorType, kPoison>::Encode(MirrorType* ptr) { uintptr_t ref = reinterpret_cast<uintptr_t>(ptr); + DCHECK_ALIGNED(ref, kObjectAlignment); if (kPoison && ref != 0) { DCHECK_LE(ref, 0xFFFFFFFFU); ref >>= kObjectAlignmentShift; @@ -52,6 +53,12 @@ inline uintptr_t ObjPtr<MirrorType, kPoison>::Encode(MirrorType* ptr) { return ref; } +template<class MirrorType, bool kPoison> +inline std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType, kPoison> ptr) { + // May be used for dumping bad pointers, do not use the checked version. + return os << ptr.DecodeUnchecked(); +} + } // namespace art #endif // ART_RUNTIME_OBJ_PTR_INL_H_ diff --git a/runtime/obj_ptr.h b/runtime/obj_ptr.h index d4076beb3c..d5ac33d8b3 100644 --- a/runtime/obj_ptr.h +++ b/runtime/obj_ptr.h @@ -17,6 +17,8 @@ #ifndef ART_RUNTIME_OBJ_PTR_H_ #define ART_RUNTIME_OBJ_PTR_H_ +#include <ostream> + #include "base/mutex.h" // For Locks::mutator_lock_. #include "globals.h" #include "mirror/object_reference.h" @@ -45,10 +47,13 @@ class ObjPtr { ALWAYS_INLINE ObjPtr(Type* ptr) REQUIRES_SHARED(Locks::mutator_lock_) : reference_(Encode(static_cast<MirrorType*>(ptr))) {} - ALWAYS_INLINE ObjPtr(const ObjPtr& other) REQUIRES_SHARED(Locks::mutator_lock_) = default; + template <typename Type> + ALWAYS_INLINE ObjPtr(const ObjPtr<Type>& other) REQUIRES_SHARED(Locks::mutator_lock_) + : reference_(Encode(static_cast<MirrorType*>(other.Decode()))) {} + template <typename Type> ALWAYS_INLINE ObjPtr& operator=(const ObjPtr& other) { - reference_ = other.reference_; + reference_ = Encode(static_cast<MirrorType*>(other.Decode())); return *this; } @@ -65,7 +70,6 @@ class ObjPtr { return Decode(); } - ALWAYS_INLINE bool IsNull() const { return reference_ == 0; } @@ -104,6 +108,16 @@ class ObjPtr { return !IsNull(); } + // Decode unchecked does not check that object pointer is valid. Do not use if you can avoid it. + ALWAYS_INLINE MirrorType* DecodeUnchecked() const REQUIRES_SHARED(Locks::mutator_lock_) { + if (kPoison) { + return reinterpret_cast<MirrorType*>( + static_cast<uintptr_t>(static_cast<uint32_t>(reference_ << kObjectAlignmentShift))); + } else { + return reinterpret_cast<MirrorType*>(reference_); + } + } + private: // Trim off high bits of thread local cookie. ALWAYS_INLINE static uintptr_t TrimCookie(uintptr_t cookie) { @@ -114,16 +128,6 @@ class ObjPtr { return reference_ >> kCookieShift; } - // Decode makes sure that the object pointer is valid. - ALWAYS_INLINE MirrorType* DecodeUnchecked() const REQUIRES_SHARED(Locks::mutator_lock_) { - if (kPoison) { - return reinterpret_cast<MirrorType*>( - static_cast<uintptr_t>(static_cast<uint32_t>(reference_ << kObjectAlignmentShift))); - } else { - return reinterpret_cast<MirrorType*>(reference_); - } - } - ALWAYS_INLINE static uintptr_t Encode(MirrorType* ptr) REQUIRES_SHARED(Locks::mutator_lock_); // The encoded reference and cookie. uintptr_t reference_; @@ -134,6 +138,10 @@ static inline ObjPtr<MirrorType, kPoison> MakeObjPtr(MirrorType* ptr) { return ObjPtr<MirrorType, kPoison>(ptr); } +template<class MirrorType, bool kPoison> +ALWAYS_INLINE std::ostream& operator<<(std::ostream& os, ObjPtr<MirrorType, kPoison> ptr) + REQUIRES_SHARED(Locks::mutator_lock_); + } // namespace art #endif // ART_RUNTIME_OBJ_PTR_H_ diff --git a/runtime/openjdkjvm/OpenjdkJvm.cc b/runtime/openjdkjvm/OpenjdkJvm.cc index 4a62ecdf4d..d46d78c2f4 100644 --- a/runtime/openjdkjvm/OpenjdkJvm.cc +++ b/runtime/openjdkjvm/OpenjdkJvm.cc @@ -43,7 +43,7 @@ #include "thread_list.h" #include "runtime.h" #include "handle_scope-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "mirror/class_loader.h" #include "verify_object-inl.h" @@ -52,7 +52,7 @@ #include "../../libcore/ojluni/src/main/native/jvm.h" // TODO(narayan): fix it #include "jni_internal.h" #include "mirror/string-inl.h" -#include "native/scoped_fast_native_object_access.h" +#include "native/scoped_fast_native_object_access-inl.h" #include "ScopedLocalRef.h" #include <sys/time.h> #include <sys/socket.h> @@ -286,9 +286,8 @@ JNIEXPORT int JVM_GetHostName(char* name, int namelen) { JNIEXPORT jstring JVM_InternString(JNIEnv* env, jstring jstr) { art::ScopedFastNativeObjectAccess soa(env); - art::mirror::String* s = soa.Decode<art::mirror::String*>(jstr); - art::mirror::String* result = s->Intern(); - return soa.AddLocalReference<jstring>(result); + art::ObjPtr<art::mirror::String> s = soa.Decode<art::mirror::String>(jstr); + return soa.AddLocalReference<jstring>(s->Intern()); } JNIEXPORT jlong JVM_FreeMemory(void) { @@ -364,8 +363,8 @@ JNIEXPORT void JVM_Yield(JNIEnv* env ATTRIBUTE_UNUSED, jclass threadClass ATTRIB JNIEXPORT void JVM_Sleep(JNIEnv* env, jclass threadClass ATTRIBUTE_UNUSED, jobject java_lock, jlong millis) { art::ScopedFastNativeObjectAccess soa(env); - art::mirror::Object* lock = soa.Decode<art::mirror::Object*>(java_lock); - art::Monitor::Wait(art::Thread::Current(), lock, millis, 0, true, art::kSleeping); + art::ObjPtr<art::mirror::Object> lock = soa.Decode<art::mirror::Object>(java_lock); + art::Monitor::Wait(art::Thread::Current(), lock.Decode(), millis, 0, true, art::kSleeping); } JNIEXPORT jobject JVM_CurrentThread(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED) { @@ -395,19 +394,19 @@ JNIEXPORT jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clea JNIEXPORT jboolean JVM_HoldsLock(JNIEnv* env, jclass unused ATTRIBUTE_UNUSED, jobject jobj) { art::ScopedObjectAccess soa(env); - art::mirror::Object* object = soa.Decode<art::mirror::Object*>(jobj); - if (object == NULL) { + art::ObjPtr<art::mirror::Object> object = soa.Decode<art::mirror::Object>(jobj); + if (object == nullptr) { art::ThrowNullPointerException("object == null"); return JNI_FALSE; } - return soa.Self()->HoldsLock(object); + return soa.Self()->HoldsLock(object.Decode()); } JNIEXPORT void JVM_SetNativeThreadName(JNIEnv* env, jobject jthread, jstring java_name) { ScopedUtfChars name(env, java_name); { art::ScopedObjectAccess soa(env); - if (soa.Decode<art::mirror::Object*>(jthread) == soa.Self()->GetPeer()) { + if (soa.Decode<art::mirror::Object>(jthread) == soa.Self()->GetPeer()) { soa.Self()->SetThreadName(name.c_str()); return; } diff --git a/runtime/openjdkjvmti/transform.cc b/runtime/openjdkjvmti/transform.cc index b5622b5cad..ac348e7246 100644 --- a/runtime/openjdkjvmti/transform.cc +++ b/runtime/openjdkjvmti/transform.cc @@ -43,7 +43,7 @@ #include "mirror/class-inl.h" #include "mirror/class_loader-inl.h" #include "mirror/string-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread_list.h" #include "transform.h" #include "utf.h" @@ -259,7 +259,7 @@ jvmtiError GetTransformationData(ArtJvmTiEnv* env, JNIEnv* jni_env = *jni_env_ptr; art::ScopedObjectAccess soa(jni_env); art::StackHandleScope<3> hs(art::Thread::Current()); - art::Handle<art::mirror::Class> hs_klass(hs.NewHandle(soa.Decode<art::mirror::Class*>(klass))); + art::Handle<art::mirror::Class> hs_klass(hs.NewHandle(soa.Decode<art::mirror::Class>(klass))); *loader = soa.AddLocalReference<jobject>(hs_klass->GetClassLoader()); *name = art::mirror::Class::ComputeName(hs_klass)->ToModifiedUtf8(); // TODO is this always null? diff --git a/runtime/proxy_test.cc b/runtime/proxy_test.cc index e3f92c7af0..43b0b3d4ff 100644 --- a/runtime/proxy_test.cc +++ b/runtime/proxy_test.cc @@ -23,7 +23,7 @@ #include "common_compiler_test.h" #include "mirror/field-inl.h" #include "mirror/method.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -108,7 +108,7 @@ TEST_F(ProxyTest, ProxyClassHelper) { jobject jclass_loader = LoadDex("Interfaces"); StackHandleScope<4> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> I(hs.NewHandle( class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader))); @@ -142,7 +142,7 @@ TEST_F(ProxyTest, ProxyFieldHelper) { jobject jclass_loader = LoadDex("Interfaces"); StackHandleScope<9> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> I(hs.NewHandle( class_linker_->FindClass(soa.Self(), "LInterfaces$I;", class_loader))); @@ -200,7 +200,7 @@ TEST_F(ProxyTest, CheckArtMirrorFieldsOfProxyStaticFields) { jobject jclass_loader = LoadDex("Interfaces"); StackHandleScope<7> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); Handle<mirror::Class> proxyClass0; Handle<mirror::Class> proxyClass1; diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc index 819e17a619..489db9aa6c 100644 --- a/runtime/reference_table_test.cc +++ b/runtime/reference_table_test.cc @@ -25,7 +25,7 @@ #include "mirror/string.h" #include "primitive.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { diff --git a/runtime/reflection.cc b/runtime/reflection.cc index 7c0f2b5115..b663b4c8ed 100644 --- a/runtime/reflection.cc +++ b/runtime/reflection.cc @@ -28,7 +28,7 @@ #include "mirror/executable.h" #include "mirror/object_array-inl.h" #include "nth_caller_visitor.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack_reference.h" #include "well_known_classes.h" @@ -115,7 +115,7 @@ class ArgArray { AppendFloat(va_arg(ap, jdouble)); break; case 'L': - Append(soa.Decode<mirror::Object*>(va_arg(ap, jobject))); + Append(soa.Decode<mirror::Object>(va_arg(ap, jobject))); break; case 'D': AppendDouble(va_arg(ap, jdouble)); @@ -157,7 +157,7 @@ class ArgArray { Append(args[args_offset].i); break; case 'L': - Append(soa.Decode<mirror::Object*>(args[args_offset].l)); + Append(soa.Decode<mirror::Object>(args[args_offset].l)); break; case 'D': case 'J': @@ -459,7 +459,7 @@ JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject o // Replace calls to String.<init> with equivalent StringFactory call. method = WellKnownClasses::StringInitToStringFactory(method); } - ObjPtr<mirror::Object> receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object>(obj); uint32_t shorty_len = 0; const char* shorty = method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len); @@ -490,7 +490,7 @@ JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, jobject o // Replace calls to String.<init> with equivalent StringFactory call. method = WellKnownClasses::StringInitToStringFactory(method); } - ObjPtr<mirror::Object> receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object>(obj); uint32_t shorty_len = 0; const char* shorty = method->GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(&shorty_len); @@ -515,7 +515,7 @@ JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnab return JValue(); } - ObjPtr<mirror::Object> receiver = soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> receiver = soa.Decode<mirror::Object>(obj); ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); if (is_string_init) { @@ -547,7 +547,7 @@ JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnab return JValue(); } - ObjPtr<mirror::Object> receiver = soa.Decode<mirror::Object*>(obj); + ObjPtr<mirror::Object> receiver = soa.Decode<mirror::Object>(obj); ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid)); bool is_string_init = method->GetDeclaringClass()->IsStringClass() && method->IsConstructor(); if (is_string_init) { @@ -580,18 +580,17 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM return nullptr; } - ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable*>(javaMethod); + ObjPtr<mirror::Executable> executable = soa.Decode<mirror::Executable>(javaMethod); const bool accessible = executable->IsAccessible(); ArtMethod* m = executable->GetArtMethod(); ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass(); if (UNLIKELY(!declaring_class->IsInitialized())) { StackHandleScope<1> hs(soa.Self()); - Handle<mirror::Class> h_class(hs.NewHandle(declaring_class.Decode())); + HandleWrapperObjPtr<mirror::Class> h_class(hs.NewHandleWrapper(&declaring_class)); if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(soa.Self(), h_class, true, true)) { return nullptr; } - declaring_class = h_class.Get(); } ObjPtr<mirror::Object> receiver; @@ -602,7 +601,7 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM CHECK(javaReceiver == nullptr); } else { // Check that the receiver is non-null and an instance of the field's declaring class. - receiver = soa.Decode<mirror::Object*>(javaReceiver); + receiver = soa.Decode<mirror::Object>(javaReceiver); if (!VerifyObjectIsClass(receiver, declaring_class)) { return nullptr; } @@ -613,7 +612,8 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM } // Get our arrays of arguments and their types, and check they're the same size. - auto* objects = soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs); + ObjPtr<mirror::ObjectArray<mirror::Object>> objects = + soa.Decode<mirror::ObjectArray<mirror::Object>>(javaArgs); auto* np_method = m->GetInterfaceMethodIfProxy(kRuntimePointerSize); const DexFile::TypeList* classes = np_method->GetParameterTypeList(); uint32_t classes_size = (classes == nullptr) ? 0 : classes->Size(); @@ -682,7 +682,7 @@ jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaM ObjPtr<mirror::Object> BoxPrimitive(Primitive::Type src_class, const JValue& value) { if (src_class == Primitive::kPrimNot) { - return value.GetL(); + return MakeObjPtr(value.GetL()); } if (src_class == Primitive::kPrimVoid) { // There's no such thing as a void field, and void methods invoked via reflection return null. diff --git a/runtime/reflection_test.cc b/runtime/reflection_test.cc index 4876ff0ff8..189ed03fb0 100644 --- a/runtime/reflection_test.cc +++ b/runtime/reflection_test.cc @@ -23,7 +23,7 @@ #include "art_method-inl.h" #include "base/enums.h" #include "common_compiler_test.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -93,16 +93,12 @@ class ReflectionTest : public CommonCompilerTest { StackHandleScope<2> hs(self); Handle<mirror::ClassLoader> class_loader( hs.NewHandle( - ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader))); - if (is_static) { - MakeExecutable(ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader), - class_name); - } else { + ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader>(jclass_loader))); + if (!is_static) { MakeExecutable(nullptr, "java.lang.Class"); MakeExecutable(nullptr, "java.lang.Object"); - MakeExecutable(ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader), - class_name); } + MakeExecutable(class_loader.Get(), class_name); mirror::Class* c = class_linker_->FindClass(self, DotToDescriptor(class_name).c_str(), class_loader); @@ -512,7 +508,7 @@ TEST_F(ReflectionTest, StaticMainMethod) { jobject jclass_loader = LoadDex("Main"); StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); CompileDirectMethod(class_loader, "Main", "main", "([Ljava/lang/String;)V"); mirror::Class* klass = class_linker_->FindClass(soa.Self(), "LMain;", class_loader); diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 65b894f05c..df0dca0237 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -133,7 +133,7 @@ #include "reflection.h" #include "runtime_options.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "sigchain.h" #include "signal_catcher.h" #include "signal_set.h" @@ -530,7 +530,7 @@ static jobject CreateSystemClassLoader(Runtime* runtime) { StackHandleScope<2> hs(soa.Self()); Handle<mirror::Class> class_loader_class( - hs.NewHandle(soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader))); + hs.NewHandle(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_ClassLoader))); CHECK(cl->EnsureInitialized(soa.Self(), class_loader_class, true, true)); ArtMethod* getSystemClassLoader = class_loader_class->FindDirectMethod( @@ -545,7 +545,7 @@ static jobject CreateSystemClassLoader(Runtime* runtime) { soa.Self()->SetClassLoaderOverride(system_class_loader.get()); Handle<mirror::Class> thread_class( - hs.NewHandle(soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread))); + hs.NewHandle(soa.Decode<mirror::Class>(WellKnownClasses::java_lang_Thread))); CHECK(cl->EnsureInitialized(soa.Self(), thread_class, true, true)); ArtField* contextClassLoader = @@ -553,8 +553,9 @@ static jobject CreateSystemClassLoader(Runtime* runtime) { CHECK(contextClassLoader != nullptr); // We can't run in a transaction yet. - contextClassLoader->SetObject<false>(soa.Self()->GetPeer(), - soa.Decode<mirror::ClassLoader*>(system_class_loader.get())); + contextClassLoader->SetObject<false>( + soa.Self()->GetPeer(), + soa.Decode<mirror::ClassLoader>(system_class_loader.get()).Decode()); return env->NewGlobalRef(system_class_loader.get()); } diff --git a/runtime/scoped_thread_state_change-inl.h b/runtime/scoped_thread_state_change-inl.h new file mode 100644 index 0000000000..cf020d0617 --- /dev/null +++ b/runtime/scoped_thread_state_change-inl.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_INL_H_ +#define ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_INL_H_ + +#include "scoped_thread_state_change.h" + +#include "jni_env_ext-inl.h" +#include "obj_ptr-inl.h" +#include "thread-inl.h" + +namespace art { + +inline ScopedThreadStateChange::ScopedThreadStateChange(Thread* self, ThreadState new_thread_state) + : self_(self), thread_state_(new_thread_state), expected_has_no_thread_(false) { + if (UNLIKELY(self_ == nullptr)) { + // Value chosen arbitrarily and won't be used in the destructor since thread_ == null. + old_thread_state_ = kTerminated; + Runtime* runtime = Runtime::Current(); + CHECK(runtime == nullptr || !runtime->IsStarted() || runtime->IsShuttingDown(self_)); + } else { + DCHECK_EQ(self, Thread::Current()); + // Read state without locks, ok as state is effectively thread local and we're not interested + // in the suspend count (this will be handled in the runnable transitions). + old_thread_state_ = self->GetState(); + if (old_thread_state_ != new_thread_state) { + if (new_thread_state == kRunnable) { + self_->TransitionFromSuspendedToRunnable(); + } else if (old_thread_state_ == kRunnable) { + self_->TransitionFromRunnableToSuspended(new_thread_state); + } else { + // A suspended transition to another effectively suspended transition, ok to use Unsafe. + self_->SetState(new_thread_state); + } + } + } +} + +inline ScopedThreadStateChange::~ScopedThreadStateChange() { + if (UNLIKELY(self_ == nullptr)) { + if (!expected_has_no_thread_) { + Runtime* runtime = Runtime::Current(); + bool shutting_down = (runtime == nullptr) || runtime->IsShuttingDown(nullptr); + CHECK(shutting_down); + } + } else { + if (old_thread_state_ != thread_state_) { + if (old_thread_state_ == kRunnable) { + self_->TransitionFromSuspendedToRunnable(); + } else if (thread_state_ == kRunnable) { + self_->TransitionFromRunnableToSuspended(old_thread_state_); + } else { + // A suspended transition to another effectively suspended transition, ok to use Unsafe. + self_->SetState(old_thread_state_); + } + } + } +} + +template<typename T> +inline T ScopedObjectAccessAlreadyRunnable::AddLocalReference(mirror::Object* obj) const { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. + DCHECK_NE(obj, Runtime::Current()->GetClearedJniWeakGlobal()); + return obj == nullptr ? nullptr : Env()->AddLocalReference<T>(obj); +} + +template<typename T, typename MirrorType, bool kPoison> +inline T ScopedObjectAccessAlreadyRunnable::AddLocalReference( + ObjPtr<MirrorType, kPoison> obj) const { + return AddLocalReference<T>(obj.Decode()); +} + +template<typename T, bool kPoison> +inline ObjPtr<T, kPoison> ScopedObjectAccessAlreadyRunnable::Decode(jobject obj) const { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. + return down_cast<T*>(Self()->DecodeJObject(obj)); +} + +inline ArtField* ScopedObjectAccessAlreadyRunnable::DecodeField(jfieldID fid) const { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. + return reinterpret_cast<ArtField*>(fid); +} + +inline jfieldID ScopedObjectAccessAlreadyRunnable::EncodeField(ArtField* field) const { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. + return reinterpret_cast<jfieldID>(field); +} + +inline ArtMethod* ScopedObjectAccessAlreadyRunnable::DecodeMethod(jmethodID mid) const { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. + return reinterpret_cast<ArtMethod*>(mid); +} + +inline jmethodID ScopedObjectAccessAlreadyRunnable::EncodeMethod(ArtMethod* method) const { + Locks::mutator_lock_->AssertSharedHeld(Self()); + DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. + return reinterpret_cast<jmethodID>(method); +} + +inline bool ScopedObjectAccessAlreadyRunnable::IsRunnable() const { + return self_->GetState() == kRunnable; +} + +inline ScopedObjectAccessAlreadyRunnable::ScopedObjectAccessAlreadyRunnable(JNIEnv* env) + : self_(ThreadForEnv(env)), env_(down_cast<JNIEnvExt*>(env)), vm_(env_->vm) {} + +inline ScopedObjectAccessAlreadyRunnable::ScopedObjectAccessAlreadyRunnable(Thread* self) + : self_(self), + env_(down_cast<JNIEnvExt*>(self->GetJniEnv())), + vm_(env_ != nullptr ? env_->vm : nullptr) {} + +inline ScopedObjectAccessUnchecked::ScopedObjectAccessUnchecked(JNIEnv* env) + : ScopedObjectAccessAlreadyRunnable(env), tsc_(Self(), kRunnable) { + Self()->VerifyStack(); + Locks::mutator_lock_->AssertSharedHeld(Self()); +} + +inline ScopedObjectAccessUnchecked::ScopedObjectAccessUnchecked(Thread* self) + : ScopedObjectAccessAlreadyRunnable(self), tsc_(self, kRunnable) { + Self()->VerifyStack(); + Locks::mutator_lock_->AssertSharedHeld(Self()); +} + +inline ScopedThreadSuspension::ScopedThreadSuspension(Thread* self, ThreadState suspended_state) + : self_(self), suspended_state_(suspended_state) { + DCHECK(self_ != nullptr); + self_->TransitionFromRunnableToSuspended(suspended_state); +} + +inline ScopedThreadSuspension::~ScopedThreadSuspension() { + DCHECK_EQ(self_->GetState(), suspended_state_); + self_->TransitionFromSuspendedToRunnable(); +} + +} // namespace art + +#endif // ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_INL_H_ diff --git a/runtime/scoped_thread_state_change.h b/runtime/scoped_thread_state_change.h index 8a1aca592f..175bec51d6 100644 --- a/runtime/scoped_thread_state_change.h +++ b/runtime/scoped_thread_state_change.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,85 +17,43 @@ #ifndef ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_H_ #define ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_H_ +#include "art_field.h" #include "base/casts.h" +#include "base/value_object.h" #include "java_vm_ext.h" -#include "jni_env_ext-inl.h" -#include "art_field.h" -#include "read_barrier.h" -#include "thread-inl.h" +#include "thread_state.h" #include "verify_object.h" namespace art { +struct JNIEnvExt; +template<class MirrorType, bool kPoison> class ObjPtr; + // Scoped change into and out of a particular state. Handles Runnable transitions that require // more complicated suspension checking. The subclasses ScopedObjectAccessUnchecked and // ScopedObjectAccess are used to handle the change into Runnable to Get direct access to objects, // the unchecked variant doesn't aid annotalysis. class ScopedThreadStateChange : public ValueObject { public: - ScopedThreadStateChange(Thread* self, ThreadState new_thread_state) - REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE - : self_(self), thread_state_(new_thread_state), expected_has_no_thread_(false) { - if (UNLIKELY(self_ == nullptr)) { - // Value chosen arbitrarily and won't be used in the destructor since thread_ == null. - old_thread_state_ = kTerminated; - Runtime* runtime = Runtime::Current(); - CHECK(runtime == nullptr || !runtime->IsStarted() || runtime->IsShuttingDown(self_)); - } else { - DCHECK_EQ(self, Thread::Current()); - // Read state without locks, ok as state is effectively thread local and we're not interested - // in the suspend count (this will be handled in the runnable transitions). - old_thread_state_ = self->GetState(); - if (old_thread_state_ != new_thread_state) { - if (new_thread_state == kRunnable) { - self_->TransitionFromSuspendedToRunnable(); - } else if (old_thread_state_ == kRunnable) { - self_->TransitionFromRunnableToSuspended(new_thread_state); - } else { - // A suspended transition to another effectively suspended transition, ok to use Unsafe. - self_->SetState(new_thread_state); - } - } - } - } + ALWAYS_INLINE ScopedThreadStateChange(Thread* self, ThreadState new_thread_state) + REQUIRES(!Locks::thread_suspend_count_lock_); - ~ScopedThreadStateChange() REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE { - if (UNLIKELY(self_ == nullptr)) { - if (!expected_has_no_thread_) { - Runtime* runtime = Runtime::Current(); - bool shutting_down = (runtime == nullptr) || runtime->IsShuttingDown(nullptr); - CHECK(shutting_down); - } - } else { - if (old_thread_state_ != thread_state_) { - if (old_thread_state_ == kRunnable) { - self_->TransitionFromSuspendedToRunnable(); - } else if (thread_state_ == kRunnable) { - self_->TransitionFromRunnableToSuspended(old_thread_state_); - } else { - // A suspended transition to another effectively suspended transition, ok to use Unsafe. - self_->SetState(old_thread_state_); - } - } - } - } + ALWAYS_INLINE ~ScopedThreadStateChange() REQUIRES(!Locks::thread_suspend_count_lock_); - Thread* Self() const { + ALWAYS_INLINE Thread* Self() const { return self_; } protected: // Constructor used by ScopedJniThreadState for an unattached thread that has access to the VM*. - ScopedThreadStateChange() - : self_(nullptr), thread_state_(kTerminated), old_thread_state_(kTerminated), - expected_has_no_thread_(true) {} + ScopedThreadStateChange() {} - Thread* const self_; - const ThreadState thread_state_; + Thread* const self_ = nullptr; + const ThreadState thread_state_ = kTerminated; private: - ThreadState old_thread_state_; - const bool expected_has_no_thread_; + ThreadState old_thread_state_ = kTerminated; + const bool expected_has_no_thread_ = true; friend class ScopedObjectAccessUnchecked; DISALLOW_COPY_AND_ASSIGN(ScopedThreadStateChange); @@ -129,62 +87,34 @@ class ScopedObjectAccessAlreadyRunnable : public ValueObject { * This will be called on otherwise unreferenced objects. We cannot do GC allocations here, and * it's best if we don't grab a mutex. */ - template<typename T> - T AddLocalReference(mirror::Object* obj) const REQUIRES_SHARED(Locks::mutator_lock_) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. - DCHECK_NE(obj, Runtime::Current()->GetClearedJniWeakGlobal()); - return obj == nullptr ? nullptr : Env()->AddLocalReference<T>(obj); - } + template<typename T, typename MirrorType, bool kPoison = kIsDebugBuild> + T AddLocalReference(ObjPtr<MirrorType, kPoison> obj) const + REQUIRES_SHARED(Locks::mutator_lock_); + // TODO: Delete template<typename T> - T Decode(jobject obj) const - REQUIRES_SHARED(Locks::mutator_lock_) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. - return down_cast<T>(Self()->DecodeJObject(obj)); - } + T AddLocalReference(mirror::Object* obj) const + REQUIRES_SHARED(Locks::mutator_lock_); - ArtField* DecodeField(jfieldID fid) const - REQUIRES_SHARED(Locks::mutator_lock_) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. - return reinterpret_cast<ArtField*>(fid); - } + template<typename T, bool kPoison = kIsDebugBuild> + ObjPtr<T, kPoison> Decode(jobject obj) const REQUIRES_SHARED(Locks::mutator_lock_); - jfieldID EncodeField(ArtField* field) const REQUIRES_SHARED(Locks::mutator_lock_) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. - return reinterpret_cast<jfieldID>(field); - } + ArtField* DecodeField(jfieldID fid) const REQUIRES_SHARED(Locks::mutator_lock_); - ArtMethod* DecodeMethod(jmethodID mid) const REQUIRES_SHARED(Locks::mutator_lock_) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. - return reinterpret_cast<ArtMethod*>(mid); - } + jfieldID EncodeField(ArtField* field) const REQUIRES_SHARED(Locks::mutator_lock_); - jmethodID EncodeMethod(ArtMethod* method) const REQUIRES_SHARED(Locks::mutator_lock_) { - Locks::mutator_lock_->AssertSharedHeld(Self()); - DCHECK(IsRunnable()); // Don't work with raw objects in non-runnable states. - return reinterpret_cast<jmethodID>(method); - } + ArtMethod* DecodeMethod(jmethodID mid) const REQUIRES_SHARED(Locks::mutator_lock_); - bool IsRunnable() const { - return self_->GetState() == kRunnable; - } + jmethodID EncodeMethod(ArtMethod* method) const REQUIRES_SHARED(Locks::mutator_lock_); + + ALWAYS_INLINE bool IsRunnable() const; protected: - explicit ScopedObjectAccessAlreadyRunnable(JNIEnv* env) - REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE - : self_(ThreadForEnv(env)), env_(down_cast<JNIEnvExt*>(env)), vm_(env_->vm) { - } + ALWAYS_INLINE explicit ScopedObjectAccessAlreadyRunnable(JNIEnv* env) + REQUIRES(!Locks::thread_suspend_count_lock_); - explicit ScopedObjectAccessAlreadyRunnable(Thread* self) - REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE - : self_(self), env_(down_cast<JNIEnvExt*>(self->GetJniEnv())), - vm_(env_ != nullptr ? env_->vm : nullptr) { - } + ALWAYS_INLINE explicit ScopedObjectAccessAlreadyRunnable(Thread* self) + REQUIRES(!Locks::thread_suspend_count_lock_); // Used when we want a scoped JNI thread state but have no thread/JNIEnv. Consequently doesn't // change into Runnable or acquire a share on the mutator_lock_. @@ -192,8 +122,7 @@ class ScopedObjectAccessAlreadyRunnable : public ValueObject { : self_(nullptr), env_(nullptr), vm_(down_cast<JavaVMExt*>(vm)) {} // Here purely to force inlining. - ~ScopedObjectAccessAlreadyRunnable() ALWAYS_INLINE { - } + ALWAYS_INLINE ~ScopedObjectAccessAlreadyRunnable() {} // Self thread, can be null. Thread* const self_; @@ -219,19 +148,11 @@ class ScopedObjectAccessAlreadyRunnable : public ValueObject { // the mutator_lock_ will be acquired on construction. class ScopedObjectAccessUnchecked : public ScopedObjectAccessAlreadyRunnable { public: - explicit ScopedObjectAccessUnchecked(JNIEnv* env) - REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE - : ScopedObjectAccessAlreadyRunnable(env), tsc_(Self(), kRunnable) { - Self()->VerifyStack(); - Locks::mutator_lock_->AssertSharedHeld(Self()); - } + ALWAYS_INLINE explicit ScopedObjectAccessUnchecked(JNIEnv* env) + REQUIRES(!Locks::thread_suspend_count_lock_); - explicit ScopedObjectAccessUnchecked(Thread* self) - REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE - : ScopedObjectAccessAlreadyRunnable(self), tsc_(self, kRunnable) { - Self()->VerifyStack(); - Locks::mutator_lock_->AssertSharedHeld(Self()); - } + ALWAYS_INLINE explicit ScopedObjectAccessUnchecked(Thread* self) + REQUIRES(!Locks::thread_suspend_count_lock_); // Used when we want a scoped JNI thread state but have no thread/JNIEnv. Consequently doesn't // change into Runnable or acquire a share on the mutator_lock_. @@ -249,28 +170,24 @@ class ScopedObjectAccessUnchecked : public ScopedObjectAccessAlreadyRunnable { // Annotalysis helping variant of the above. class ScopedObjectAccess : public ScopedObjectAccessUnchecked { public: - explicit ScopedObjectAccess(JNIEnv* env) + ALWAYS_INLINE explicit ScopedObjectAccess(JNIEnv* env) REQUIRES(!Locks::thread_suspend_count_lock_) - SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE - : ScopedObjectAccessUnchecked(env) { - } + SHARED_LOCK_FUNCTION(Locks::mutator_lock_) + : ScopedObjectAccessUnchecked(env) {} - explicit ScopedObjectAccess(Thread* self) + ALWAYS_INLINE explicit ScopedObjectAccess(Thread* self) REQUIRES(!Locks::thread_suspend_count_lock_) - SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE - : ScopedObjectAccessUnchecked(self) { - } + SHARED_LOCK_FUNCTION(Locks::mutator_lock_) + : ScopedObjectAccessUnchecked(self) {} - ~ScopedObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE { - // Base class will release share of lock. Invoked after this destructor. - } + // Base class will release share of lock. Invoked after this destructor. + ~ScopedObjectAccess() UNLOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE {} private: // TODO: remove this constructor. It is used by check JNI's ScopedCheck to make it believe that // routines operating with just a VM are sound, they are not, but when you have just a VM // you cannot call the unsound routines. - explicit ScopedObjectAccess(JavaVM* vm) - SHARED_LOCK_FUNCTION(Locks::mutator_lock_) + explicit ScopedObjectAccess(JavaVM* vm) SHARED_LOCK_FUNCTION(Locks::mutator_lock_) : ScopedObjectAccessUnchecked(vm) {} friend class ScopedCheck; @@ -280,19 +197,11 @@ class ScopedObjectAccess : public ScopedObjectAccessUnchecked { // Annotalysis helper for going to a suspended state from runnable. class ScopedThreadSuspension : public ValueObject { public: - explicit ScopedThreadSuspension(Thread* self, ThreadState suspended_state) + ALWAYS_INLINE explicit ScopedThreadSuspension(Thread* self, ThreadState suspended_state) REQUIRES(!Locks::thread_suspend_count_lock_, !Roles::uninterruptible_) - UNLOCK_FUNCTION(Locks::mutator_lock_) - ALWAYS_INLINE - : self_(self), suspended_state_(suspended_state) { - DCHECK(self_ != nullptr); - self_->TransitionFromRunnableToSuspended(suspended_state); - } + UNLOCK_FUNCTION(Locks::mutator_lock_); - ~ScopedThreadSuspension() SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE { - DCHECK_EQ(self_->GetState(), suspended_state_); - self_->TransitionFromSuspendedToRunnable(); - } + ALWAYS_INLINE ~ScopedThreadSuspension() SHARED_LOCK_FUNCTION(Locks::mutator_lock_); private: Thread* const self_; diff --git a/runtime/signal_catcher.cc b/runtime/signal_catcher.cc index 848c0e3b90..674459df5d 100644 --- a/runtime/signal_catcher.cc +++ b/runtime/signal_catcher.cc @@ -34,7 +34,7 @@ #include "gc/heap.h" #include "os.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "signal_set.h" #include "thread.h" #include "thread_list.h" diff --git a/runtime/thread.cc b/runtime/thread.cc index d0ea2d7569..ec1bb3fa13 100644 --- a/runtime/thread.cc +++ b/runtime/thread.cc @@ -59,12 +59,13 @@ #include "native_stack_dump.h" #include "nth_caller_visitor.h" #include "oat_quick_method_header.h" +#include "obj_ptr-inl.h" #include "object_lock.h" #include "quick_exception_handler.h" #include "quick/quick_method_frame_info.h" #include "reflection.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "ScopedUtfChars.h" #include "stack.h" @@ -406,7 +407,7 @@ void* Thread::CreateCallback(void* arg) { // Copy peer into self, deleting global reference when done. CHECK(self->tlsPtr_.jpeer != nullptr); - self->tlsPtr_.opeer = soa.Decode<mirror::Object*>(self->tlsPtr_.jpeer); + self->tlsPtr_.opeer = soa.Decode<mirror::Object>(self->tlsPtr_.jpeer).Decode(); self->GetJniEnv()->DeleteGlobalRef(self->tlsPtr_.jpeer); self->tlsPtr_.jpeer = nullptr; self->SetThreadName(self->GetThreadName(soa)->ToModifiedUtf8().c_str()); @@ -444,7 +445,7 @@ Thread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa, Thread* Thread::FromManagedThread(const ScopedObjectAccessAlreadyRunnable& soa, jobject java_thread) { - return FromManagedThread(soa, soa.Decode<mirror::Object*>(java_thread)); + return FromManagedThread(soa, soa.Decode<mirror::Object>(java_thread).Decode()); } static size_t FixStackSize(size_t stack_size) { @@ -563,7 +564,7 @@ void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_siz ArtField* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name); mirror::String* java_name = reinterpret_cast<mirror::String*>(f->GetObject( - soa.Decode<mirror::Object*>(java_peer))); + soa.Decode<mirror::Object>(java_peer).Decode())); std::string thread_name; if (java_name != nullptr) { thread_name = java_name->ToModifiedUtf8(); @@ -802,7 +803,7 @@ void Thread::CreatePeer(const char* name, bool as_daemon, jobject thread_group) } { ScopedObjectAccess soa(this); - tlsPtr_.opeer = soa.Decode<mirror::Object*>(peer.get()); + tlsPtr_.opeer = soa.Decode<mirror::Object>(peer.get()).Decode(); } env->CallNonvirtualVoidMethod(peer.get(), WellKnownClasses::java_lang_Thread, @@ -844,9 +845,11 @@ void Thread::InitPeer(ScopedObjectAccess& soa, jboolean thread_is_daemon, jobjec soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon)-> SetBoolean<kTransactionActive>(tlsPtr_.opeer, thread_is_daemon); soa.DecodeField(WellKnownClasses::java_lang_Thread_group)-> - SetObject<kTransactionActive>(tlsPtr_.opeer, soa.Decode<mirror::Object*>(thread_group)); + SetObject<kTransactionActive>(tlsPtr_.opeer, + soa.Decode<mirror::Object>(thread_group).Decode()); soa.DecodeField(WellKnownClasses::java_lang_Thread_name)-> - SetObject<kTransactionActive>(tlsPtr_.opeer, soa.Decode<mirror::Object*>(thread_name)); + SetObject<kTransactionActive>(tlsPtr_.opeer, + soa.Decode<mirror::Object>(thread_name).Decode()); soa.DecodeField(WellKnownClasses::java_lang_Thread_priority)-> SetInt<kTransactionActive>(tlsPtr_.opeer, thread_priority); } @@ -2123,7 +2126,7 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray( int* stack_depth) { // Decode the internal stack trace into the depth, method trace and PC trace. // Subtract one for the methods and PC trace. - int32_t depth = soa.Decode<mirror::Array*>(internal)->GetLength() - 1; + int32_t depth = soa.Decode<mirror::Array>(internal)->GetLength() - 1; DCHECK_GE(depth, 0); ClassLinker* const class_linker = Runtime::Current()->GetClassLinker(); @@ -2135,7 +2138,7 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray( result = output_array; // ...adjusting the number of frames we'll write to not exceed the array length. const int32_t traces_length = - soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(result)->GetLength(); + soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>>(result)->GetLength(); depth = std::min(depth, traces_length); } else { // Create java_trace array and place in local reference table @@ -2153,7 +2156,7 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray( for (int32_t i = 0; i < depth; ++i) { mirror::ObjectArray<mirror::Object>* decoded_traces = - soa.Decode<mirror::Object*>(internal)->AsObjectArray<mirror::Object>(); + soa.Decode<mirror::Object>(internal)->AsObjectArray<mirror::Object>(); // Methods and dex PC trace is element 0. DCHECK(decoded_traces->Get(0)->IsIntArray() || decoded_traces->Get(0)->IsLongArray()); mirror::PointerArray* const method_trace = @@ -2205,7 +2208,7 @@ jobjectArray Thread::InternalStackTraceToStackTraceElementArray( return nullptr; } // We are called from native: use non-transactional mode. - soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(result)->Set<false>(i, obj); + soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>>(result)->Set<false>(i, obj); } return result; } @@ -3044,11 +3047,10 @@ void Thread::DeoptimizeWithDeoptimizationException(JValue* result) { interpreter::EnterInterpreterFromDeoptimize(this, shadow_frame, from_code, result); } -void Thread::SetException(mirror::Throwable* new_exception) { +void Thread::SetException(ObjPtr<mirror::Throwable> new_exception) { CHECK(new_exception != nullptr); // TODO: DCHECK(!IsExceptionPending()); - tlsPtr_.exception = new_exception; - // LOG(ERROR) << new_exception->Dump(); + tlsPtr_.exception = new_exception.Decode(); } } // namespace art diff --git a/runtime/thread.h b/runtime/thread.h index 55f1489389..f2c22d17a9 100644 --- a/runtime/thread.h +++ b/runtime/thread.h @@ -366,7 +366,7 @@ class Thread { void AssertNoPendingException() const; void AssertNoPendingExceptionForNewException(const char* msg) const; - void SetException(mirror::Throwable* new_exception) REQUIRES_SHARED(Locks::mutator_lock_); + void SetException(ObjPtr<mirror::Throwable> new_exception) REQUIRES_SHARED(Locks::mutator_lock_); void ClearException() REQUIRES_SHARED(Locks::mutator_lock_) { tlsPtr_.exception = nullptr; @@ -902,7 +902,9 @@ class Thread { // Returns the fake exception used to activate deoptimization. static mirror::Throwable* GetDeoptimizationException() { - return reinterpret_cast<mirror::Throwable*>(-1); + // Note that the mirror::Throwable must be aligned to kObjectAlignment or else it cannot be + // represented by ObjPtr. + return reinterpret_cast<mirror::Throwable*>(0x100); } // Currently deoptimization invokes verifier which can trigger class loading diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc index 17c6c2e65d..e2aca6ad49 100644 --- a/runtime/thread_list.cc +++ b/runtime/thread_list.cc @@ -36,7 +36,7 @@ #include "lock_word.h" #include "monitor.h" #include "native_stack_dump.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" #include "trace.h" #include "well_known_classes.h" diff --git a/runtime/trace.cc b/runtime/trace.cc index 23591c257a..f846746779 100644 --- a/runtime/trace.cc +++ b/runtime/trace.cc @@ -37,7 +37,7 @@ #include "mirror/object_array-inl.h" #include "mirror/object-inl.h" #include "os.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedLocalRef.h" #include "thread.h" #include "thread_list.h" diff --git a/runtime/transaction_test.cc b/runtime/transaction_test.cc index 82e529c5ab..77c2b76bbb 100644 --- a/runtime/transaction_test.cc +++ b/runtime/transaction_test.cc @@ -22,7 +22,7 @@ #include "common_runtime_test.h" #include "dex_file.h" #include "mirror/array-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -36,7 +36,7 @@ class TransactionTest : public CommonRuntimeTest { jobject jclass_loader = LoadDex("Transaction"); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(jclass_loader))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(jclass_loader))); ASSERT_TRUE(class_loader.Get() != nullptr); // Load and initialize java.lang.ExceptionInInitializerError and the exception class used @@ -173,7 +173,7 @@ TEST_F(TransactionTest, StaticFieldsTest) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<4> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction")))); ASSERT_TRUE(class_loader.Get() != nullptr); Handle<mirror::Class> h_klass( @@ -271,7 +271,7 @@ TEST_F(TransactionTest, InstanceFieldsTest) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<5> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction")))); ASSERT_TRUE(class_loader.Get() != nullptr); Handle<mirror::Class> h_klass( @@ -373,7 +373,7 @@ TEST_F(TransactionTest, StaticArrayFieldsTest) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<4> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction")))); ASSERT_TRUE(class_loader.Get() != nullptr); Handle<mirror::Class> h_klass( @@ -490,7 +490,7 @@ TEST_F(TransactionTest, ResolveString) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<3> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction")))); ASSERT_TRUE(class_loader.Get() != nullptr); Handle<mirror::Class> h_klass( @@ -539,7 +539,7 @@ TEST_F(TransactionTest, EmptyClass) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction")))); ASSERT_TRUE(class_loader.Get() != nullptr); Handle<mirror::Class> h_klass( @@ -563,7 +563,7 @@ TEST_F(TransactionTest, StaticFieldClass) { ScopedObjectAccess soa(Thread::Current()); StackHandleScope<2> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(LoadDex("Transaction")))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(LoadDex("Transaction")))); ASSERT_TRUE(class_loader.Get() != nullptr); Handle<mirror::Class> h_klass( diff --git a/runtime/type_lookup_table_test.cc b/runtime/type_lookup_table_test.cc index ea4d8b5ee0..ec38b4154e 100644 --- a/runtime/type_lookup_table_test.cc +++ b/runtime/type_lookup_table_test.cc @@ -19,7 +19,7 @@ #include "common_runtime_test.h" #include "dex_file-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "type_lookup_table.h" #include "utf-inl.h" diff --git a/runtime/utils.cc b/runtime/utils.cc index 0803ca744a..a40e313118 100644 --- a/runtime/utils.cc +++ b/runtime/utils.cc @@ -39,7 +39,7 @@ #include "oat_quick_method_header.h" #include "obj_ptr-inl.h" #include "os.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "utf-inl.h" #if defined(__APPLE__) diff --git a/runtime/utils_test.cc b/runtime/utils_test.cc index 3ba20a4f02..ef4222285d 100644 --- a/runtime/utils_test.cc +++ b/runtime/utils_test.cc @@ -26,7 +26,7 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "mirror/string.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "handle_scope-inl.h" #include "base/memory_tool.h" diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 13ef043174..87b6dc3a88 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -46,7 +46,7 @@ #include "reg_type-inl.h" #include "register_line-inl.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "utils.h" #include "verifier_deps.h" #include "handle_scope-inl.h" diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc index 646987a1e5..837ee2d396 100644 --- a/runtime/verifier/method_verifier_test.cc +++ b/runtime/verifier/method_verifier_test.cc @@ -22,7 +22,7 @@ #include "class_linker-inl.h" #include "common_runtime_test.h" #include "dex_file.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "verifier_log_mode.h" namespace art { diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc index 3bc2acc1f3..a84668ba02 100644 --- a/runtime/verifier/reg_type.cc +++ b/runtime/verifier/reg_type.cc @@ -27,7 +27,7 @@ #include "mirror/object-inl.h" #include "mirror/object_array-inl.h" #include "reg_type_cache-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include <limits> #include <sstream> diff --git a/runtime/verifier/reg_type_test.cc b/runtime/verifier/reg_type_test.cc index f2411b56fd..49dac26bb4 100644 --- a/runtime/verifier/reg_type_test.cc +++ b/runtime/verifier/reg_type_test.cc @@ -24,7 +24,7 @@ #include "common_runtime_test.h" #include "reg_type_cache-inl.h" #include "reg_type-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { diff --git a/runtime/verifier/verifier_deps_test.cc b/runtime/verifier/verifier_deps_test.cc index bbaf59fef6..4533464baa 100644 --- a/runtime/verifier/verifier_deps_test.cc +++ b/runtime/verifier/verifier_deps_test.cc @@ -25,7 +25,7 @@ #include "mirror/class_loader.h" #include "runtime.h" #include "thread.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { namespace verifier { @@ -58,7 +58,7 @@ class VerifierDepsTest : public CommonRuntimeTest { REQUIRES_SHARED(Locks::mutator_lock_) { StackHandleScope<1> hs(Thread::Current()); Handle<mirror::ClassLoader> class_loader_handle( - hs.NewHandle(soa->Decode<mirror::ClassLoader*>(class_loader_))); + hs.NewHandle(soa->Decode<mirror::ClassLoader>(class_loader_))); mirror::Class* klass = class_linker_->FindClass(Thread::Current(), name.c_str(), class_loader_handle); @@ -84,8 +84,8 @@ class VerifierDepsTest : public CommonRuntimeTest { SetVerifierDeps(dex_files); - mirror::ClassLoader* loader = soa->Decode<mirror::ClassLoader*>(class_loader_); - class_linker_->RegisterDexFile(*dex_file_, loader); + ObjPtr<mirror::ClassLoader> loader = soa->Decode<mirror::ClassLoader>(class_loader_); + class_linker_->RegisterDexFile(*dex_file_, loader.Decode()); klass_Main_ = FindClassByName("LMain;", soa); CHECK(klass_Main_ != nullptr); @@ -97,7 +97,7 @@ class VerifierDepsTest : public CommonRuntimeTest { StackHandleScope<2> hs(Thread::Current()); Handle<mirror::ClassLoader> class_loader_handle( - hs.NewHandle(soa.Decode<mirror::ClassLoader*>(class_loader_))); + hs.NewHandle(soa.Decode<mirror::ClassLoader>(class_loader_))); Handle<mirror::DexCache> dex_cache_handle(hs.NewHandle(klass_Main_->GetDexCache())); const DexFile::ClassDef* class_def = klass_Main_->GetClassDef(); diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc index e5216fbcff..4dcf58fc93 100644 --- a/runtime/well_known_classes.cc +++ b/runtime/well_known_classes.cc @@ -25,7 +25,7 @@ #include "mirror/class.h" #include "mirror/throwable.h" #include "ScopedLocalRef.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { diff --git a/test/004-ThreadStress/thread_stress.cc b/test/004-ThreadStress/thread_stress.cc index 573c352423..8ae3dfb540 100644 --- a/test/004-ThreadStress/thread_stress.cc +++ b/test/004-ThreadStress/thread_stress.cc @@ -19,18 +19,18 @@ #include "jni.h" #include "mirror/string.h" #include "mirror/throwable.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { extern "C" JNIEXPORT void JNICALL Java_Main_printString(JNIEnv*, jclass, jstring s) { ScopedObjectAccess soa(Thread::Current()); - std::cout << soa.Decode<mirror::String*>(s)->ToModifiedUtf8(); + std::cout << soa.Decode<mirror::String>(s)->ToModifiedUtf8(); } extern "C" JNIEXPORT void JNICALL Java_Main_printThrowable(JNIEnv*, jclass, jthrowable t) { ScopedObjectAccess soa(Thread::Current()); - std::cout << soa.Decode<mirror::Throwable*>(t)->Dump(); + std::cout << soa.Decode<mirror::Throwable>(t)->Dump(); } } // namespace art diff --git a/test/004-UnsafeTest/unsafe_test.cc b/test/004-UnsafeTest/unsafe_test.cc index 3b0cf235a6..4f6ae5a68d 100644 --- a/test/004-UnsafeTest/unsafe_test.cc +++ b/test/004-UnsafeTest/unsafe_test.cc @@ -20,20 +20,20 @@ #include "mirror/class.h" #include "mirror/class-inl.h" #include "mirror/object-inl.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { extern "C" JNIEXPORT jint JNICALL Java_Main_vmArrayBaseOffset(JNIEnv* env, jclass, jobject classObj) { ScopedObjectAccess soa(env); - mirror::Class* klass = soa.Decode<mirror::Class*>(classObj); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(classObj); return mirror::Array::DataOffset( Primitive::ComponentSize(klass->GetComponentType()->GetPrimitiveType())).Int32Value(); } extern "C" JNIEXPORT jint JNICALL Java_Main_vmArrayIndexScale(JNIEnv* env, jclass, jobject classObj) { ScopedObjectAccess soa(env); - mirror::Class* klass = soa.Decode<mirror::Class*>(classObj); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(classObj); return Primitive::ComponentSize(klass->GetComponentType()->GetPrimitiveType()); } diff --git a/test/117-nopatchoat/nopatchoat.cc b/test/117-nopatchoat/nopatchoat.cc index c6a2e9a5a8..56c0dcd41b 100644 --- a/test/117-nopatchoat/nopatchoat.cc +++ b/test/117-nopatchoat/nopatchoat.cc @@ -20,7 +20,7 @@ #include "gc/space/image_space.h" #include "mirror/class-inl.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread.h" namespace art { @@ -29,7 +29,7 @@ class NoPatchoatTest { public: static const OatFile::OatDexFile* getOatDexFile(jclass cls) { ScopedObjectAccess soa(Thread::Current()); - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); const DexFile& dex_file = klass->GetDexFile(); return dex_file.GetOatDexFile(); } diff --git a/test/1337-gc-coverage/gc_coverage.cc b/test/1337-gc-coverage/gc_coverage.cc index 7cf30bd5b9..1e60bd9c8e 100644 --- a/test/1337-gc-coverage/gc_coverage.cc +++ b/test/1337-gc-coverage/gc_coverage.cc @@ -17,7 +17,7 @@ #include "gc/heap.h" #include "jni.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { @@ -43,7 +43,7 @@ extern "C" JNIEXPORT void JNICALL Java_Main_decrementDisableMovingGC(JNIEnv*, jc extern "C" JNIEXPORT jlong JNICALL Java_Main_objectAddress(JNIEnv* env, jclass, jobject object) { ScopedObjectAccess soa(env); - return reinterpret_cast<jlong>(soa.Decode<mirror::Object*>(object)); + return reinterpret_cast<jlong>(soa.Decode<mirror::Object>(object).Decode()); } extern "C" JNIEXPORT jboolean JNICALL Java_Main_supportCollectorTransition(JNIEnv*, jclass) { diff --git a/test/148-multithread-gc-annotations/gc_coverage.cc b/test/148-multithread-gc-annotations/gc_coverage.cc index 263eefd3ab..cb12df4a8e 100644 --- a/test/148-multithread-gc-annotations/gc_coverage.cc +++ b/test/148-multithread-gc-annotations/gc_coverage.cc @@ -17,7 +17,7 @@ #include "gc/heap.h" #include "jni.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "thread-inl.h" namespace art { @@ -35,7 +35,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_MovingGCThread_supportHomogeneousSpac extern "C" JNIEXPORT jlong JNICALL Java_MovingGCThread_objectAddress(JNIEnv* env, jclass, jobject object) { ScopedObjectAccess soa(env); - return reinterpret_cast<jlong>(soa.Decode<mirror::Object*>(object)); + return reinterpret_cast<jlong>(soa.Decode<mirror::Object>(object).Decode()); } } // namespace diff --git a/test/454-get-vreg/get_vreg_jni.cc b/test/454-get-vreg/get_vreg_jni.cc index 57627543e0..9058af43d1 100644 --- a/test/454-get-vreg/get_vreg_jni.cc +++ b/test/454-get-vreg/get_vreg_jni.cc @@ -18,7 +18,7 @@ #include "art_method-inl.h" #include "jni.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread.h" @@ -123,7 +123,7 @@ class TestVisitor : public StackVisitor { extern "C" JNIEXPORT jint JNICALL Java_Main_doNativeCall(JNIEnv*, jobject value) { ScopedObjectAccess soa(Thread::Current()); std::unique_ptr<Context> context(Context::Create()); - TestVisitor visitor(soa.Self(), context.get(), soa.Decode<mirror::Object*>(value)); + TestVisitor visitor(soa.Self(), context.get(), soa.Decode<mirror::Object>(value).Decode()); visitor.WalkStack(); return visitor.found_method_index_; } diff --git a/test/457-regs/regs_jni.cc b/test/457-regs/regs_jni.cc index 08db7755a4..f62a77d793 100644 --- a/test/457-regs/regs_jni.cc +++ b/test/457-regs/regs_jni.cc @@ -18,7 +18,7 @@ #include "art_method-inl.h" #include "jni.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread.h" @@ -139,7 +139,7 @@ extern "C" JNIEXPORT void JNICALL Java_PhiLiveness_regsNativeCallWithParameters( JNIEnv*, jclass value ATTRIBUTE_UNUSED, jobject main, jint int_value, jfloat float_value) { ScopedObjectAccess soa(Thread::Current()); std::unique_ptr<Context> context(Context::Create()); - CHECK(soa.Decode<mirror::Object*>(main) == nullptr); + CHECK(soa.Decode<mirror::Object>(main) == nullptr); CHECK_EQ(int_value, 0); int32_t cast = bit_cast<int32_t, float>(float_value); CHECK_EQ(cast, 0); diff --git a/test/461-get-reference-vreg/get_reference_vreg_jni.cc b/test/461-get-reference-vreg/get_reference_vreg_jni.cc index 8122c6d7cd..7b1ab9c5be 100644 --- a/test/461-get-reference-vreg/get_reference_vreg_jni.cc +++ b/test/461-get-reference-vreg/get_reference_vreg_jni.cc @@ -17,7 +17,7 @@ #include "arch/context.h" #include "art_method-inl.h" #include "jni.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread.h" @@ -70,7 +70,7 @@ class TestVisitor : public StackVisitor { extern "C" JNIEXPORT jint JNICALL Java_Main_doNativeCallRef(JNIEnv*, jobject value) { ScopedObjectAccess soa(Thread::Current()); std::unique_ptr<Context> context(Context::Create()); - TestVisitor visitor(soa.Self(), context.get(), soa.Decode<mirror::Object*>(value)); + TestVisitor visitor(soa.Self(), context.get(), soa.Decode<mirror::Object>(value).Decode()); visitor.WalkStack(); return visitor.found_method_index_; } diff --git a/test/466-get-live-vreg/get_live_vreg_jni.cc b/test/466-get-live-vreg/get_live_vreg_jni.cc index 3618b4f52a..d3a033b12a 100644 --- a/test/466-get-live-vreg/get_live_vreg_jni.cc +++ b/test/466-get-live-vreg/get_live_vreg_jni.cc @@ -18,7 +18,7 @@ #include "art_method-inl.h" #include "jni.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread.h" diff --git a/test/497-inlining-and-class-loader/clear_dex_cache.cc b/test/497-inlining-and-class-loader/clear_dex_cache.cc index 1597c4a65d..3f2df29472 100644 --- a/test/497-inlining-and-class-loader/clear_dex_cache.cc +++ b/test/497-inlining-and-class-loader/clear_dex_cache.cc @@ -17,7 +17,7 @@ #include "art_method-inl.h" #include "base/enums.h" #include "jni.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread.h" @@ -29,7 +29,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_Main_cloneResolvedMethods(JNIEnv* env, jclass, jclass cls) { ScopedObjectAccess soa(Thread::Current()); - mirror::DexCache* dex_cache = soa.Decode<mirror::Class*>(cls)->GetDexCache(); + mirror::DexCache* dex_cache = soa.Decode<mirror::Class>(cls)->GetDexCache(); size_t num_methods = dex_cache->NumResolvedMethods(); ArtMethod** methods = dex_cache->GetResolvedMethods(); CHECK_EQ(num_methods != 0u, methods != nullptr); @@ -43,7 +43,7 @@ extern "C" JNIEXPORT jobject JNICALL Java_Main_cloneResolvedMethods(JNIEnv* env, array = env->NewLongArray(num_methods); } CHECK(array != nullptr); - mirror::PointerArray* pointer_array = soa.Decode<mirror::PointerArray*>(array); + mirror::PointerArray* pointer_array = soa.Decode<mirror::PointerArray>(array).Decode(); for (size_t i = 0; i != num_methods; ++i) { ArtMethod* method = mirror::DexCache::GetElementPtrSize(methods, i, kRuntimePointerSize); pointer_array->SetElementPtrSize(i, method, kRuntimePointerSize); @@ -54,11 +54,11 @@ extern "C" JNIEXPORT jobject JNICALL Java_Main_cloneResolvedMethods(JNIEnv* env, extern "C" JNIEXPORT void JNICALL Java_Main_restoreResolvedMethods( JNIEnv*, jclass, jclass cls, jobject old_cache) { ScopedObjectAccess soa(Thread::Current()); - mirror::DexCache* dex_cache = soa.Decode<mirror::Class*>(cls)->GetDexCache(); + mirror::DexCache* dex_cache = soa.Decode<mirror::Class>(cls)->GetDexCache(); size_t num_methods = dex_cache->NumResolvedMethods(); - ArtMethod** methods = soa.Decode<mirror::Class*>(cls)->GetDexCache()->GetResolvedMethods(); + ArtMethod** methods = soa.Decode<mirror::Class>(cls)->GetDexCache()->GetResolvedMethods(); CHECK_EQ(num_methods != 0u, methods != nullptr); - mirror::PointerArray* old = soa.Decode<mirror::PointerArray*>(old_cache); + ObjPtr<mirror::PointerArray> old = soa.Decode<mirror::PointerArray>(old_cache); CHECK_EQ(methods != nullptr, old != nullptr); CHECK_EQ(num_methods, static_cast<size_t>(old->GetLength())); for (size_t i = 0; i != num_methods; ++i) { diff --git a/test/543-env-long-ref/env_long_ref.cc b/test/543-env-long-ref/env_long_ref.cc index 557def6d0a..cd127ef3cb 100644 --- a/test/543-env-long-ref/env_long_ref.cc +++ b/test/543-env-long-ref/env_long_ref.cc @@ -17,7 +17,7 @@ #include "arch/context.h" #include "art_method-inl.h" #include "jni.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread.h" @@ -43,7 +43,7 @@ class TestVisitor : public StackVisitor { uint32_t value = 0; CHECK(GetVReg(m, 1, kReferenceVReg, &value)); CHECK_EQ(reinterpret_cast<mirror::Object*>(value), - soa_.Decode<mirror::Object*>(expected_value_)); + soa_.Decode<mirror::Object>(expected_value_).Decode()); } return true; } diff --git a/test/566-polymorphic-inlining/polymorphic_inline.cc b/test/566-polymorphic-inlining/polymorphic_inline.cc index 89293cc38a..00c1b02675 100644 --- a/test/566-polymorphic-inlining/polymorphic_inline.cc +++ b/test/566-polymorphic-inlining/polymorphic_inline.cc @@ -20,14 +20,14 @@ #include "jit/jit_code_cache.h" #include "jit/profiling_info.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack_map.h" namespace art { static void do_checks(jclass cls, const char* method_name) { ScopedObjectAccess soa(Thread::Current()); - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); jit::Jit* jit = Runtime::Current()->GetJit(); jit::JitCodeCache* code_cache = jit->GetCodeCache(); ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, kRuntimePointerSize); @@ -53,7 +53,7 @@ static void do_checks(jclass cls, const char* method_name) { static void allocate_profiling_info(jclass cls, const char* method_name) { ScopedObjectAccess soa(Thread::Current()); - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); ArtMethod* method = klass->FindDeclaredDirectMethodByName(method_name, kRuntimePointerSize); ProfilingInfo::Create(soa.Self(), method, /* retry_allocation */ true); } diff --git a/test/570-checker-osr/osr.cc b/test/570-checker-osr/osr.cc index adda3ccb5b..50e8382ff6 100644 --- a/test/570-checker-osr/osr.cc +++ b/test/570-checker-osr/osr.cc @@ -19,7 +19,7 @@ #include "jit/jit_code_cache.h" #include "jit/profiling_info.h" #include "oat_quick_method_header.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "stack_map.h" diff --git a/test/595-profile-saving/profile-saving.cc b/test/595-profile-saving/profile-saving.cc index a265dce409..bf3d812f94 100644 --- a/test/595-profile-saving/profile-saving.cc +++ b/test/595-profile-saving/profile-saving.cc @@ -24,7 +24,7 @@ #include "mirror/class-inl.h" #include "oat_file_assistant.h" #include "oat_file_manager.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "thread.h" @@ -74,7 +74,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_presentInProfile( ScopedUtfChars filename_chars(env, filename); CHECK(filename_chars.c_str() != nullptr); ScopedObjectAccess soa(Thread::Current()); - const DexFile* dex_file = soa.Decode<mirror::Class*>(cls)->GetDexCache()->GetDexFile(); + const DexFile* dex_file = soa.Decode<mirror::Class>(cls)->GetDexCache()->GetDexFile(); return ProfileSaver::HasSeenMethod(std::string(filename_chars.c_str()), dex_file, static_cast<uint16_t>(method_index)); diff --git a/test/596-app-images/app_images.cc b/test/596-app-images/app_images.cc index a5bbf5fbaa..78cc3fd118 100644 --- a/test/596-app-images/app_images.cc +++ b/test/596-app-images/app_images.cc @@ -26,7 +26,7 @@ #include "jni.h" #include "mirror/class.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" namespace art { @@ -48,13 +48,13 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_checkAppImageLoaded(JNIEnv*, jcl extern "C" JNIEXPORT jboolean JNICALL Java_Main_checkAppImageContains(JNIEnv*, jclass, jclass c) { ScopedObjectAccess soa(Thread::Current()); - mirror::Class* klass_ptr = soa.Decode<mirror::Class*>(c); + ObjPtr<mirror::Class> klass_ptr = soa.Decode<mirror::Class>(c); for (auto* space : Runtime::Current()->GetHeap()->GetContinuousSpaces()) { if (space->IsImageSpace()) { auto* image_space = space->AsImageSpace(); const auto& image_header = image_space->GetImageHeader(); if (image_header.IsAppImage()) { - if (image_space->HasAddress(klass_ptr)) { + if (image_space->HasAddress(klass_ptr.Decode())) { return JNI_TRUE; } } diff --git a/test/Android.bp b/test/Android.bp index 72dcbba9e2..628f3772e0 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -110,7 +110,7 @@ art_cc_defaults { "-Wl,-u,Java_MyClassNatives_sbar", ], shared_libs: [ - "libcutils", + "liblog", "libdl", "libz", ], diff --git a/test/common/runtime_state.cc b/test/common/runtime_state.cc index fd1ba020dd..42481483f4 100644 --- a/test/common/runtime_state.cc +++ b/test/common/runtime_state.cc @@ -24,7 +24,7 @@ #include "mirror/class-inl.h" #include "oat_quick_method_header.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "ScopedUtfChars.h" #include "thread-inl.h" @@ -35,7 +35,7 @@ namespace art { extern "C" JNIEXPORT jboolean JNICALL Java_Main_hasOatFile(JNIEnv* env, jclass cls) { ScopedObjectAccess soa(env); - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); const DexFile& dex_file = klass->GetDexFile(); const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile(); return (oat_dex_file != nullptr) ? JNI_TRUE : JNI_FALSE; @@ -75,7 +75,7 @@ extern "C" JNIEXPORT jboolean JNICALL Java_Main_isImageDex2OatEnabled(JNIEnv* en extern "C" JNIEXPORT jboolean JNICALL Java_Main_compiledWithOptimizing(JNIEnv* env, jclass cls) { ScopedObjectAccess soa(env); - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); const DexFile& dex_file = klass->GetDexFile(); const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile(); if (oat_dex_file == nullptr) { @@ -134,7 +134,7 @@ extern "C" JNIEXPORT void JNICALL Java_Main_ensureJitCompiled(JNIEnv* env, ScopedUtfChars chars(env, method_name); CHECK(chars.c_str() != nullptr); - method = soa.Decode<mirror::Class*>(cls)->FindDeclaredDirectMethodByName( + method = soa.Decode<mirror::Class>(cls)->FindDeclaredDirectMethodByName( chars.c_str(), kRuntimePointerSize); } diff --git a/test/common/stack_inspect.cc b/test/common/stack_inspect.cc index 85ea1c8dd1..d2aacf0562 100644 --- a/test/common/stack_inspect.cc +++ b/test/common/stack_inspect.cc @@ -21,7 +21,7 @@ #include "mirror/class-inl.h" #include "nth_caller_visitor.h" #include "runtime.h" -#include "scoped_thread_state_change.h" +#include "scoped_thread_state_change-inl.h" #include "stack.h" #include "thread-inl.h" @@ -62,7 +62,7 @@ extern "C" JNIEXPORT void JNICALL Java_Main_assertIsInterpreted(JNIEnv* env, jcl static jboolean IsManaged(JNIEnv* env, jclass cls, size_t level) { ScopedObjectAccess soa(env); - mirror::Class* klass = soa.Decode<mirror::Class*>(cls); + ObjPtr<mirror::Class> klass = soa.Decode<mirror::Class>(cls); const DexFile& dex_file = klass->GetDexFile(); const OatFile::OatDexFile* oat_dex_file = dex_file.GetOatDexFile(); if (oat_dex_file == nullptr) { diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar index c51cb0db2a..d8f42a2b4b 100755 --- a/test/etc/run-test-jar +++ b/test/etc/run-test-jar @@ -404,6 +404,24 @@ if [ "$HOST" = "n" ]; then fi fi +# Prevent test from silently falling back to interpreter in no-prebuild mode. This happens +# when DEX_LOCATION path is too long, because vdex/odex filename is constructed by taking +# full path to dex, stripping leading '/', appending '@classes.vdex' and changing every +# remaining '/' into '@'. +if [ "$HOST" = "y" ]; then + max_filename_size=$(getconf NAME_MAX $DEX_LOCATION) +else + # There is no getconf on device, fallback to standard value. See NAME_MAX in kernel <linux/limits.h> + max_filename_size=255 +fi +# Compute VDEX_NAME. +DEX_LOCATION_STRIPPED="${DEX_LOCATION#/}" +VDEX_NAME="${DEX_LOCATION_STRIPPED//\//@}@$TEST_NAME.jar@classes.vdex" +if [ ${#VDEX_NAME} -gt $max_filename_size ]; then + echo "Dex location path too long." + exit 1 +fi + dex2oat_cmdline="true" mkdir_locations="${DEX_LOCATION}/dalvik-cache/$ISA" strip_cmdline="true" |