Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Runtime.smali   Sprache: unbekannt

 
Spracherkennung für: .smali vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

# 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.

.class public LRuntime;
.super Ljava/lang/Object;

# The following tests all share the same structure, signature and return values:
#  - foo(false, false):  normal path,         returns 42
#  - foo(true, false):   exceptional path #1, returns 3
#  - foo(false, true):   exceptional path #2, returns 8
#  - foo(true, true):    undefined


# Test register allocation of 32-bit core intervals crossing catch block positions.

## CHECK-START: int Runtime.testUseAfterCatch_int(boolean, boolean) register (after)
## CHECK-NOT:     Phi is_catch_phi:true

.method public static testUseAfterCatch_int(ZZ)I
  .registers 6

  sget-object v0, LRuntime;->intArray:[I
  const/4 v1, 0
  aget v1, v0, v1
  const/4 v2, 1
  aget v2, v0, v2
  const/4 v3, 2
  aget v3, v0, v3

  :try_start
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  return v3  # Normal path return.

  :catch_all
  if-eqz p0, :second_throw
  return v1  # Exceptional path #1 return.

  :second_throw
  return v2  # Exceptional path #2 return.
.end method


# Test register allocation of 64-bit core intervals crossing catch block positions.

# The sum of the low and high 32 bits treated as integers is returned to prove
# that both vregs allocated correctly.

## CHECK-START: int Runtime.testUseAfterCatch_long(boolean, boolean) register (after)
## CHECK-NOT:     Phi is_catch_phi:true

.method public static testUseAfterCatch_long(ZZ)I
  .registers 10

  sget-object v0, LRuntime;->longArray:[J
  const/4 v1, 0
  aget-wide v1, v0, v1
  const/4 v3, 1
  aget-wide v3, v0, v3
  const/4 v5, 2
  aget-wide v5, v0, v5

  :try_start
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  const v0, 32
  ushr-long v7, v5, v0
  long-to-int v5, v5
  long-to-int v7, v7
  add-int/2addr v5, v7
  return v5  # Normal path return.

  :catch_all
  const v0, 32
  if-eqz p0, :second_throw

  ushr-long v7, v1, v0
  long-to-int v1, v1
  long-to-int v7, v7
  add-int/2addr v1, v7
  return v1  # Exceptional path #1 return.

  :second_throw
  ushr-long v7, v3, v0
  long-to-int v3, v3
  long-to-int v7, v7
  add-int/2addr v3, v7
  return v3  # Exceptional path #2 return.
.end method


# Test register allocation of 32-bit floating-point intervals crossing catch block positions.

## CHECK-START: int Runtime.testUseAfterCatch_float(boolean, boolean) register (after)
## CHECK-NOT:     Phi is_catch_phi:true

.method public static testUseAfterCatch_float(ZZ)I
  .registers 6

  sget-object v0, LRuntime;->floatArray:[F
  const/4 v1, 0
  aget v1, v0, v1
  const/4 v2, 1
  aget v2, v0, v2
  const/4 v3, 2
  aget v3, v0, v3

  :try_start
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  float-to-int v3, v3
  return v3  # Normal path return.

  :catch_all
  if-eqz p0, :second_throw
  float-to-int v1, v1
  return v1  # Exceptional path #1 return.

  :second_throw
  float-to-int v2, v2
  return v2  # Exceptional path #2 return.
.end method


# Test register allocation of 64-bit floating-point intervals crossing catch block positions.

## CHECK-START: int Runtime.testUseAfterCatch_double(boolean, boolean) register (after)
## CHECK-NOT:     Phi is_catch_phi:true

.method public static testUseAfterCatch_double(ZZ)I
  .registers 10

  sget-object v0, LRuntime;->doubleArray:[D
  const/4 v1, 0
  aget-wide v1, v0, v1
  const/4 v3, 1
  aget-wide v3, v0, v3
  const/4 v5, 2
  aget-wide v5, v0, v5

  :try_start
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  double-to-int v5, v5
  return v5  # Normal path return.

  :catch_all
  if-eqz p0, :second_throw
  double-to-int v1, v1
  return v1  # Exceptional path #1 return.

  :second_throw
  double-to-int v3, v3
  return v3  # Exceptional path #2 return.
.end method


# Test catch-phi runtime support for constant values.

# Register v0 holds different constants at two throwing instructions. Runtime is
# expected to load them from stack map and copy to the catch phi's location.

## CHECK-START: int Runtime.testCatchPhi_const(boolean, boolean) register (after)
## CHECK-DAG:     <<Const3:i\d+>> IntConstant 3
## CHECK-DAG:     <<Const8:i\d+>> IntConstant 8
## CHECK-DAG:                     Phi [<<Const3>>,<<Const8>>] is_catch_phi:true

.method public static testCatchPhi_const(ZZ)I
  .registers 3

  :try_start
  const v0, 3
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  const v0, 8
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  const v0, 42
  return v0  # Normal path return.

  :catch_all
  return v0  # Exceptional path #1/#2 return.
.end method


# Test catch-phi runtime support for 32-bit values stored in core registers.

# Register v0 holds different integer values at two throwing instructions.
# Runtime is expected to find their location in the stack map and copy the value
# to the location of the catch phi.

## CHECK-START: int Runtime.testCatchPhi_int(boolean, boolean) register (after)
## CHECK-DAG:     <<Val1:i\d+>> ArrayGet
## CHECK-DAG:     <<Val2:i\d+>> ArrayGet
## CHECK-DAG:                   Phi [<<Val1>>,<<Val2>>] is_catch_phi:true

.method public static testCatchPhi_int(ZZ)I
  .registers 6

  sget-object v0, LRuntime;->intArray:[I
  const/4 v1, 0
  aget v1, v0, v1
  const/4 v2, 1
  aget v2, v0, v2
  const/4 v3, 2
  aget v3, v0, v3

  :try_start
  move v0, v1  # Set catch phi value
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  move v0, v2  # Set catch phi value
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  return v3  # Normal path return.

  :catch_all
  return v0  # Exceptional path #1/#2 return.
.end method


# Test catch-phi runtime support for 64-bit values stored in core registers.

# Register pair (v0, v1) holds different long values at two throwing instructions.
# Runtime is expected to find their location in the stack map and copy the value
# to the location of the catch phi. The sum of the low and high 32 bits treated
# as integers is returned to prove that both vregs were copied.

# Note: values will be spilled on x86 because of too few callee-save core registers.

## CHECK-START: int Runtime.testCatchPhi_long(boolean, boolean) register (after)
## CHECK-DAG:     <<Val1:j\d+>> ArrayGet
## CHECK-DAG:     <<Val2:j\d+>> ArrayGet
## CHECK-DAG:                   Phi [<<Val1>>,<<Val2>>] is_catch_phi:true

.method public static testCatchPhi_long(ZZ)I
  .registers 10

  sget-object v0, LRuntime;->longArray:[J
  const/4 v2, 0
  aget-wide v2, v0, v2
  const/4 v4, 1
  aget-wide v4, v0, v4
  const/4 v6, 2
  aget-wide v6, v0, v6

  :try_start
  move-wide v0, v2  # Set catch phi value
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  move-wide v0, v4  # Set catch phi value
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  const v2, 32
  ushr-long v2, v6, v2
  long-to-int v2, v2
  long-to-int v6, v6
  add-int/2addr v6, v2
  return v6  # Normal path return.

  :catch_all
  const v2, 32
  ushr-long v2, v0, v2
  long-to-int v2, v2
  long-to-int v0, v0
  add-int/2addr v0, v2
  return v0  # Exceptional path #1/#2 return.
.end method


# Test catch-phi runtime support for 32-bit values stored in FPU registers.

# Register v0 holds different float values at two throwing instructions. Runtime
# is expected to find their location in the stack map and copy the value to the
# location of the catch phi. The value is converted to int and returned.

# Note: values will be spilled on x86 as there are no callee-save FPU registers.

## CHECK-START: int Runtime.testCatchPhi_float(boolean, boolean) register (after)
## CHECK-DAG:     <<Val1:f\d+>> ArrayGet
## CHECK-DAG:     <<Val2:f\d+>> ArrayGet
## CHECK-DAG:                   Phi [<<Val1>>,<<Val2>>] is_catch_phi:true

.method public static testCatchPhi_float(ZZ)I
  .registers 6

  sget-object v0, LRuntime;->floatArray:[F
  const/4 v1, 0
  aget v1, v0, v1
  const/4 v2, 1
  aget v2, v0, v2
  const/4 v3, 2
  aget v3, v0, v3

  :try_start
  move v0, v1  # Set catch phi value
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  move v0, v2  # Set catch phi value
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  float-to-int v3, v3
  return v3  # Normal path return.

  :catch_all
  float-to-int v0, v0
  return v0  # Exceptional path #1/#2 return.
.end method


# Test catch-phi runtime support for 64-bit values stored in FPU registers.

# Register pair (v0, v1) holds different double values at two throwing instructions.
# Runtime is expected to find their location in the stack map and copy the value
# to the location of the catch phi. The value is converted to int and returned.
# Values were chosen so that all 64 bits are used.

# Note: values will be spilled on x86 as there are no callee-save FPU registers.

## CHECK-START: int Runtime.testCatchPhi_double(boolean, boolean) register (after)
## CHECK-DAG:     <<Val1:d\d+>> ArrayGet
## CHECK-DAG:     <<Val2:d\d+>> ArrayGet
## CHECK-DAG:                   Phi [<<Val1>>,<<Val2>>] is_catch_phi:true

.method public static testCatchPhi_double(ZZ)I
  .registers 10

  sget-object v0, LRuntime;->doubleArray:[D
  const/4 v2, 0
  aget-wide v2, v0, v2
  const/4 v4, 1
  aget-wide v4, v0, v4
  const/4 v6, 2
  aget-wide v6, v0, v6

  :try_start
  move-wide v0, v2  # Set catch phi value
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  move-wide v0, v4  # Set catch phi value
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  double-to-int v6, v6
  return v6

  :catch_all
  double-to-int v0, v0
  return v0
.end method

# Test catch-phi runtime support for 32-bit values stored on the stack.

# Register v0 holds different integer values at two throwing instructions.
# These values were forced to spill by an always-throwing try/catch after their
# definition. Runtime is expected to find their location in the stack map and
# copy the value to the location of the catch phi. The value is then returned.

## CHECK-START: int Runtime.testCatchPhi_singleSlot(boolean, boolean) register (after)
## CHECK:         <<Val1:i\d+>> ArrayGet
## CHECK-NEXT:                  ParallelMove moves:[{{.*->}}{{\d+}}(sp)]
## CHECK:         <<Val2:i\d+>> ArrayGet
## CHECK-NEXT:                  ParallelMove moves:[{{.*->}}{{\d+}}(sp)]
## CHECK:                       Phi [<<Val1>>,<<Val2>>] is_catch_phi:true

.method public static testCatchPhi_singleSlot(ZZ)I
  .registers 6

  sget-object v0, LRuntime;->intArray:[I
  const/4 v1, 0
  aget v1, v0, v1
  const/4 v2, 1
  aget v2, v0, v2
  const/4 v3, 2
  aget v3, v0, v3

  # Insert a try/catch to force v1,v2,v3 to spill.
  :try_start_spill
  const/4 v0, 1
  invoke-static {v0}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end_spill
  .catchall {:try_start_spill .. :try_end_spill} :catch_all_spill
  return v0         # Unreachable
  :catch_all_spill  # Catch and continue

  :try_start
  move v0, v1  # Set catch phi value
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  move v0, v2  # Set catch phi value
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  return v3  # Normal path return.

  :catch_all
  return v0  # Exceptional path #1/#2 return.
.end method

# Test catch-phi runtime support for 64-bit values stored on the stack.

# Register pair (v0, v1) holds different double values at two throwing instructions.
# These values were forced to spill by an always-throwing try/catch after their
# definition. Runtime is expected to find their location in the stack map and
# copy the value to the location of the catch phi. The value is converted to int
# and returned. Values were chosen so that all 64 bits are used.

## CHECK-START: int Runtime.testCatchPhi_doubleSlot(boolean, boolean) register (after)
## CHECK:         <<Val1:d\d+>> ArrayGet
## CHECK-NEXT:                  ParallelMove moves:[{{.*->}}2x{{\d+}}(sp)]
## CHECK:         <<Val2:d\d+>> ArrayGet
## CHECK-NEXT:                  ParallelMove moves:[{{.*->}}2x{{\d+}}(sp)]
## CHECK:                       Phi [<<Val1>>,<<Val2>>] is_catch_phi:true

.method public static testCatchPhi_doubleSlot(ZZ)I
  .registers 10

  sget-object v0, LRuntime;->doubleArray:[D
  const/4 v2, 0
  aget-wide v2, v0, v2
  const/4 v4, 1
  aget-wide v4, v0, v4
  const/4 v6, 2
  aget-wide v6, v0, v6

  # Insert a try/catch to force (v2, v3), (v4, v5), (v6, v7) to spill.
  :try_start_spill
  const/4 v0, 1
  invoke-static {v0}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end_spill
  .catchall {:try_start_spill .. :try_end_spill} :catch_all_spill
  return v0         # Unreachable
  :catch_all_spill  # Catch and continue

  :try_start
  move-wide v0, v2  # Set catch phi value
  invoke-static {p0}, LRuntime;->$noinline$ThrowIfTrue(Z)V

  move-wide v0, v4  # Set catch phi value
  invoke-static {p1}, LRuntime;->$noinline$ThrowIfTrue(Z)V
  :try_end
  .catchall {:try_start .. :try_end} :catch_all

  double-to-int v6, v6
  return v6  # Normal path return.

  :catch_all
  double-to-int v0, v0
  return v0  # Exceptional path #1/#2 return.
.end method



# Helper methods and initialization.

.method public static $noinline$ThrowIfTrue(Z)V
  .registers 2
  if-nez p0, :throw
  return-void

  :throw
  new-instance v0, Ljava/lang/Exception;
  invoke-direct {v0}, Ljava/lang/Exception;-><init>()V
  throw v0
.end method

.method public static constructor <clinit>()V
  .registers 2

  const/4 v1, 4

  new-array v0, v1, [I
  fill-array-data v0, :array_int
  sput-object v0, LRuntime;->intArray:[I

  new-array v0, v1, [J
  fill-array-data v0, :array_long
  sput-object v0, LRuntime;->longArray:[J

  new-array v0, v1, [F
  fill-array-data v0, :array_float
  sput-object v0, LRuntime;->floatArray:[F

  new-array v0, v1, [D
  fill-array-data v0, :array_double
  sput-object v0, LRuntime;->doubleArray:[D

  return-void

:array_int
.array-data 4
  0x03  # int 3
  0x08  # int 8
  0x2a  # int 42
.end array-data

:array_long
.array-data 8
  0x0000000100000002L # long (1 << 32) + 2
  0x0000000500000003L # long (5 << 32) + 3
  0x0000001e0000000cL # long (30 << 32) + 12
.end array-data

:array_float
.array-data 4
  0x40400000  # float 3
  0x41000000  # float 8
  0x42280000  # float 42
.end array-data

:array_double
.array-data 8
  0x400b333333333333L  # double 3.4
  0x4020cccccccccccdL  # double 8.4
  0x4045333333333333L  # double 42.4
.end array-data
.end method


## CHECK-START-{ARM,ARM64}: int Runtime.testIntAddressCatch(int, int[]) GVN$after_arch (after)
## CHECK-DAG: <<Const1:i\d+>>       IntConstant 1
## CHECK-DAG: <<Offset:i\d+>>       IntConstant 12
## CHECK-DAG: <<IndexParam:i\d+>>   ParameterValue
## CHECK-DAG: <<Array:l\d+>>        ParameterValue

## CHECK-DAG: <<NullCh1:l\d+>>      NullCheck [<<Array>>]
## CHECK-DAG: <<Length:i\d+>>       ArrayLength
## CHECK-DAG: <<BoundsCh1:i\d+>>    BoundsCheck [<<IndexParam>>,<<Length>>]
## CHECK-DAG: <<IntAddr1:i\d+>>     IntermediateAddress [<<NullCh1>>,<<Offset>>]
## CHECK-DAG:                       ArrayGet [<<IntAddr1>>,<<BoundsCh1>>]
## CHECK-DAG:                       TryBoundary

## CHECK-DAG: <<Xplus1:i\d+>>       Add [<<IndexParam>>,<<Const1>>]
## CHECK-DAG: <<BoundsCh2:i\d+>>    BoundsCheck [<<Xplus1>>,<<Length>>]
## CHECK-DAG:                       ArrayGet [<<IntAddr1>>,<<BoundsCh2>>]
## CHECK-DAG:                       TryBoundary

## CHECK-DAG: <<Phi:i\d+>>          Phi [<<Xplus1>>]
## CHECK-DAG: <<Phiplus1:i\d+>>     Add [<<Phi>>,<<Const1>>]
## CHECK-DAG: <<BoundsCh3:i\d+>>    BoundsCheck [<<Phiplus1>>,<<Length>>]
## CHECK-DAG: <<IntAddr3:i\d+>>     IntermediateAddress [<<NullCh1>>,<<Offset>>]
## CHECK-DAG:                       ArrayGet [<<IntAddr3>>,<<BoundsCh3>>]

## CHECK-START-{ARM,ARM64}: int Runtime.testIntAddressCatch(int, int[]) GVN$after_arch (after)
## CHECK:                           NullCheck
## CHECK-NOT:                       NullCheck

## CHECK-START-{ARM,ARM64}: int Runtime.testIntAddressCatch(int, int[]) GVN$after_arch (after)
## CHECK:                           IntermediateAddress
## CHECK:                           IntermediateAddress
## CHECK-NOT:                       IntermediateAddress

## CHECK-START-{ARM,ARM64}: int Runtime.testIntAddressCatch(int, int[]) GVN$after_arch (after)
## CHECK:                           BoundsCheck
## CHECK:                           BoundsCheck
## CHECK:                           BoundsCheck
## CHECK-NOT:                       BoundsCheck

## CHECK-START-{ARM,ARM64}: int Runtime.testIntAddressCatch(int, int[]) GVN$after_arch (after)
## CHECK:                           ArrayGet
## CHECK:                           ArrayGet
## CHECK:                           ArrayGet
## CHECK-NOT:                       ArrayGet
.method public static testIntAddressCatch(I[I)I
    .registers 4
    aget v0, p1, p0
    add-int v1, v0, v0

    :try_start
    const/4 v0, 0x1
    add-int p0, p0, v0
    aget v0, p1, p0

    :try_end
    .catch Ljava/lang/ArithmException; {:try_start .. :try_end} :catch_block

    :return
    add-int v1, v1, v0
    return v1

    :catch_block
    const/4 v0, 0x1
    add-int p0, p0, v0
    aget v0, p1, p0

    goto :return
.end method

.field public static intArray:[I
.field public static longArray:[J
.field public static floatArray:[F
.field public static doubleArray:[D

[Dauer der Verarbeitung: 0.22 Sekunden, vorverarbeitet 2026-06-29]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik