src/share/vm/shark/sharkInliner.cpp

changeset 2047
d2ede61b7a12
child 2314
f95d63e2154a
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/shark/sharkInliner.cpp	Wed Aug 11 05:51:21 2010 -0700
     1.3 @@ -0,0 +1,749 @@
     1.4 +/*
     1.5 + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright 2009 Red Hat, Inc.
     1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8 + *
     1.9 + * This code is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License version 2 only, as
    1.11 + * published by the Free Software Foundation.
    1.12 + *
    1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 + * version 2 for more details (a copy is included in the LICENSE file that
    1.17 + * accompanied this code).
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License version
    1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 + *
    1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 + * or visit www.oracle.com if you need additional information or have any
    1.25 + * questions.
    1.26 + *
    1.27 + */
    1.28 +
    1.29 +#include "incls/_precompiled.incl"
    1.30 +#include "incls/_sharkInliner.cpp.incl"
    1.31 +
    1.32 +using namespace llvm;
    1.33 +
    1.34 +class SharkInlineBlock : public SharkBlock {
    1.35 + public:
    1.36 +  SharkInlineBlock(ciMethod* target, SharkState* state)
    1.37 +    : SharkBlock(state, target),
    1.38 +      _outer_state(state),
    1.39 +      _entry_state(new SharkState(this)) {
    1.40 +    for (int i = target->max_locals() - 1; i >= 0; i--) {
    1.41 +      SharkValue *value = NULL;
    1.42 +      if (i < target->arg_size())
    1.43 +        value = outer_state()->pop();
    1.44 +      entry_state()->set_local(i, value);
    1.45 +    }
    1.46 +  }
    1.47 +
    1.48 + private:
    1.49 +  SharkState* _outer_state;
    1.50 +  SharkState* _entry_state;
    1.51 +
    1.52 + private:
    1.53 +  SharkState* outer_state() {
    1.54 +    return _outer_state;
    1.55 +  }
    1.56 +  SharkState* entry_state() {
    1.57 +    return _entry_state;
    1.58 +  }
    1.59 +
    1.60 + public:
    1.61 +  void emit_IR() {
    1.62 +    parse_bytecode(0, target()->code_size());
    1.63 +  }
    1.64 +
    1.65 + private:
    1.66 +  void do_return(BasicType type) {
    1.67 +    if (type != T_VOID) {
    1.68 +      SharkValue *result = pop_result(type);
    1.69 +      outer_state()->push(result);
    1.70 +      if (result->is_two_word())
    1.71 +        outer_state()->push(NULL);
    1.72 +    }
    1.73 +  }
    1.74 +};
    1.75 +
    1.76 +class SharkInlinerHelper : public StackObj {
    1.77 + public:
    1.78 +  SharkInlinerHelper(ciMethod* target, SharkState* entry_state)
    1.79 +    : _target(target),
    1.80 +      _entry_state(entry_state),
    1.81 +      _iter(target) {}
    1.82 +
    1.83 + private:
    1.84 +  ciBytecodeStream _iter;
    1.85 +  SharkState*      _entry_state;
    1.86 +  ciMethod*        _target;
    1.87 +
    1.88 + public:
    1.89 +  ciBytecodeStream* iter() {
    1.90 +    return &_iter;
    1.91 +  }
    1.92 +  SharkState* entry_state() const {
    1.93 +    return _entry_state;
    1.94 +  }
    1.95 +  ciMethod* target() const {
    1.96 +    return _target;
    1.97 +  }
    1.98 +
    1.99 + public:
   1.100 +  Bytecodes::Code bc() {
   1.101 +    return iter()->cur_bc();
   1.102 +  }
   1.103 +  int max_locals() const {
   1.104 +    return target()->max_locals();
   1.105 +  }
   1.106 +  int max_stack() const {
   1.107 +    return target()->max_stack();
   1.108 +  }
   1.109 +
   1.110 +  // Inlinability check
   1.111 + public:
   1.112 +  bool is_inlinable();
   1.113 +
   1.114 + private:
   1.115 +  void initialize_for_check();
   1.116 +
   1.117 +  bool do_getstatic() {
   1.118 +    return do_field_access(true, false);
   1.119 +  }
   1.120 +  bool do_getfield() {
   1.121 +    return do_field_access(true, true);
   1.122 +  }
   1.123 +  bool do_putfield() {
   1.124 +    return do_field_access(false, true);
   1.125 +  }
   1.126 +  bool do_field_access(bool is_get, bool is_field);
   1.127 +
   1.128 +  // Local variables for inlinability check
   1.129 + private:
   1.130 +  bool* _locals;
   1.131 +
   1.132 + public:
   1.133 +  bool* local_addr(int index) const {
   1.134 +    assert(index >= 0 && index < max_locals(), "bad local variable index");
   1.135 +    return &_locals[index];
   1.136 +  }
   1.137 +  bool local(int index) const {
   1.138 +    return *local_addr(index);
   1.139 +  }
   1.140 +  void set_local(int index, bool value) {
   1.141 +    *local_addr(index) = value;
   1.142 +  }
   1.143 +
   1.144 +  // Expression stack for inlinability check
   1.145 + private:
   1.146 +  bool* _stack;
   1.147 +  bool* _sp;
   1.148 +
   1.149 + public:
   1.150 +  int stack_depth() const {
   1.151 +    return _sp - _stack;
   1.152 +  }
   1.153 +  bool* stack_addr(int slot) const {
   1.154 +    assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
   1.155 +    return &_sp[-(slot + 1)];
   1.156 +  }
   1.157 +  void push(bool value) {
   1.158 +    assert(stack_depth() < max_stack(), "stack overrun");
   1.159 +    *(_sp++) = value;
   1.160 +  }
   1.161 +  bool pop() {
   1.162 +    assert(stack_depth() > 0, "stack underrun");
   1.163 +    return *(--_sp);
   1.164 +  }
   1.165 +
   1.166 +  // Methods for two-word locals
   1.167 + public:
   1.168 +  void push_pair_local(int index) {
   1.169 +    push(local(index));
   1.170 +    push(local(index + 1));
   1.171 +  }
   1.172 +  void pop_pair_local(int index) {
   1.173 +    set_local(index + 1, pop());
   1.174 +    set_local(index, pop());
   1.175 +  }
   1.176 +
   1.177 +  // Code generation
   1.178 + public:
   1.179 +  void do_inline() {
   1.180 +    (new SharkInlineBlock(target(), entry_state()))->emit_IR();
   1.181 +  }
   1.182 +};
   1.183 +
   1.184 +// Quick checks so we can bail out before doing too much
   1.185 +bool SharkInliner::may_be_inlinable(ciMethod *target) {
   1.186 +  // We can't inline native methods
   1.187 +  if (target->is_native())
   1.188 +    return false;
   1.189 +
   1.190 +  // Not much point inlining abstract ones, and in any
   1.191 +  // case we'd need a stack frame to throw the exception
   1.192 +  if (target->is_abstract())
   1.193 +    return false;
   1.194 +
   1.195 +  // Don't inline anything huge
   1.196 +  if (target->code_size() > SharkMaxInlineSize)
   1.197 +    return false;
   1.198 +
   1.199 +  // Monitors aren't allowed without a frame to put them in
   1.200 +  if (target->is_synchronized() || target->has_monitor_bytecodes())
   1.201 +    return false;
   1.202 +
   1.203 +  // We don't do control flow
   1.204 +  if (target->has_exception_handlers() || target->has_jsrs())
   1.205 +    return false;
   1.206 +
   1.207 +  // Don't try to inline constructors, as they must
   1.208 +  // eventually call Object.<init> which we can't inline.
   1.209 +  // Note that this catches <clinit> too, but why would
   1.210 +  // we be compiling that?
   1.211 +  if (target->is_initializer())
   1.212 +    return false;
   1.213 +
   1.214 +  // Mustn't inline Object.<init>
   1.215 +  // Should be caught by the above, but just in case...
   1.216 +  if (target->intrinsic_id() == vmIntrinsics::_Object_init)
   1.217 +    return false;
   1.218 +
   1.219 +  return true;
   1.220 +}
   1.221 +
   1.222 +// Full-on detailed check, for methods that pass the quick checks
   1.223 +// Inlined methods have no stack frame, so we can't do anything
   1.224 +// that would require one.  This means no safepoints (and hence
   1.225 +// no loops) and no VM calls.  No VM calls means, amongst other
   1.226 +// things, that no exceptions can be created, which means no null
   1.227 +// checks or divide-by-zero checks are allowed.  The lack of null
   1.228 +// checks in particular would eliminate practically everything,
   1.229 +// but we can get around that restriction by relying on the zero-
   1.230 +// check eliminator to strip the checks.  To do that, we need to
   1.231 +// walk through the method, tracking which values are and are not
   1.232 +// zero-checked.
   1.233 +bool SharkInlinerHelper::is_inlinable() {
   1.234 +  ResourceMark rm;
   1.235 +  initialize_for_check();
   1.236 +
   1.237 +  SharkConstant *sc;
   1.238 +  bool a, b, c, d;
   1.239 +
   1.240 +  iter()->reset_to_bci(0);
   1.241 +  while (iter()->next() != ciBytecodeStream::EOBC()) {
   1.242 +    switch (bc()) {
   1.243 +    case Bytecodes::_nop:
   1.244 +      break;
   1.245 +
   1.246 +    case Bytecodes::_aconst_null:
   1.247 +      push(false);
   1.248 +      break;
   1.249 +
   1.250 +    case Bytecodes::_iconst_0:
   1.251 +      push(false);
   1.252 +      break;
   1.253 +    case Bytecodes::_iconst_m1:
   1.254 +    case Bytecodes::_iconst_1:
   1.255 +    case Bytecodes::_iconst_2:
   1.256 +    case Bytecodes::_iconst_3:
   1.257 +    case Bytecodes::_iconst_4:
   1.258 +    case Bytecodes::_iconst_5:
   1.259 +      push(true);
   1.260 +      break;
   1.261 +
   1.262 +    case Bytecodes::_lconst_0:
   1.263 +      push(false);
   1.264 +      push(false);
   1.265 +      break;
   1.266 +    case Bytecodes::_lconst_1:
   1.267 +      push(true);
   1.268 +      push(false);
   1.269 +      break;
   1.270 +
   1.271 +    case Bytecodes::_fconst_0:
   1.272 +    case Bytecodes::_fconst_1:
   1.273 +    case Bytecodes::_fconst_2:
   1.274 +      push(false);
   1.275 +      break;
   1.276 +
   1.277 +    case Bytecodes::_dconst_0:
   1.278 +    case Bytecodes::_dconst_1:
   1.279 +      push(false);
   1.280 +      push(false);
   1.281 +      break;
   1.282 +
   1.283 +    case Bytecodes::_bipush:
   1.284 +      push(iter()->get_constant_u1() != 0);
   1.285 +      break;
   1.286 +    case Bytecodes::_sipush:
   1.287 +      push(iter()->get_constant_u2() != 0);
   1.288 +      break;
   1.289 +
   1.290 +    case Bytecodes::_ldc:
   1.291 +    case Bytecodes::_ldc_w:
   1.292 +    case Bytecodes::_ldc2_w:
   1.293 +      sc = SharkConstant::for_ldc(iter());
   1.294 +      if (!sc->is_loaded())
   1.295 +        return false;
   1.296 +      push(sc->is_nonzero());
   1.297 +      if (sc->is_two_word())
   1.298 +        push(false);
   1.299 +      break;
   1.300 +
   1.301 +    case Bytecodes::_iload_0:
   1.302 +    case Bytecodes::_fload_0:
   1.303 +    case Bytecodes::_aload_0:
   1.304 +      push(local(0));
   1.305 +      break;
   1.306 +    case Bytecodes::_lload_0:
   1.307 +    case Bytecodes::_dload_0:
   1.308 +      push_pair_local(0);
   1.309 +      break;
   1.310 +
   1.311 +    case Bytecodes::_iload_1:
   1.312 +    case Bytecodes::_fload_1:
   1.313 +    case Bytecodes::_aload_1:
   1.314 +      push(local(1));
   1.315 +      break;
   1.316 +    case Bytecodes::_lload_1:
   1.317 +    case Bytecodes::_dload_1:
   1.318 +      push_pair_local(1);
   1.319 +      break;
   1.320 +
   1.321 +    case Bytecodes::_iload_2:
   1.322 +    case Bytecodes::_fload_2:
   1.323 +    case Bytecodes::_aload_2:
   1.324 +      push(local(2));
   1.325 +      break;
   1.326 +    case Bytecodes::_lload_2:
   1.327 +    case Bytecodes::_dload_2:
   1.328 +      push_pair_local(2);
   1.329 +      break;
   1.330 +
   1.331 +    case Bytecodes::_iload_3:
   1.332 +    case Bytecodes::_fload_3:
   1.333 +    case Bytecodes::_aload_3:
   1.334 +      push(local(3));
   1.335 +      break;
   1.336 +    case Bytecodes::_lload_3:
   1.337 +    case Bytecodes::_dload_3:
   1.338 +      push_pair_local(3);
   1.339 +      break;
   1.340 +
   1.341 +    case Bytecodes::_iload:
   1.342 +    case Bytecodes::_fload:
   1.343 +    case Bytecodes::_aload:
   1.344 +      push(local(iter()->get_index()));
   1.345 +      break;
   1.346 +    case Bytecodes::_lload:
   1.347 +    case Bytecodes::_dload:
   1.348 +      push_pair_local(iter()->get_index());
   1.349 +      break;
   1.350 +
   1.351 +    case Bytecodes::_istore_0:
   1.352 +    case Bytecodes::_fstore_0:
   1.353 +    case Bytecodes::_astore_0:
   1.354 +      set_local(0, pop());
   1.355 +      break;
   1.356 +    case Bytecodes::_lstore_0:
   1.357 +    case Bytecodes::_dstore_0:
   1.358 +      pop_pair_local(0);
   1.359 +      break;
   1.360 +
   1.361 +    case Bytecodes::_istore_1:
   1.362 +    case Bytecodes::_fstore_1:
   1.363 +    case Bytecodes::_astore_1:
   1.364 +      set_local(1, pop());
   1.365 +      break;
   1.366 +    case Bytecodes::_lstore_1:
   1.367 +    case Bytecodes::_dstore_1:
   1.368 +      pop_pair_local(1);
   1.369 +      break;
   1.370 +
   1.371 +    case Bytecodes::_istore_2:
   1.372 +    case Bytecodes::_fstore_2:
   1.373 +    case Bytecodes::_astore_2:
   1.374 +      set_local(2, pop());
   1.375 +      break;
   1.376 +    case Bytecodes::_lstore_2:
   1.377 +    case Bytecodes::_dstore_2:
   1.378 +      pop_pair_local(2);
   1.379 +      break;
   1.380 +
   1.381 +    case Bytecodes::_istore_3:
   1.382 +    case Bytecodes::_fstore_3:
   1.383 +    case Bytecodes::_astore_3:
   1.384 +      set_local(3, pop());
   1.385 +      break;
   1.386 +    case Bytecodes::_lstore_3:
   1.387 +    case Bytecodes::_dstore_3:
   1.388 +      pop_pair_local(3);
   1.389 +      break;
   1.390 +
   1.391 +    case Bytecodes::_istore:
   1.392 +    case Bytecodes::_fstore:
   1.393 +    case Bytecodes::_astore:
   1.394 +      set_local(iter()->get_index(), pop());
   1.395 +      break;
   1.396 +    case Bytecodes::_lstore:
   1.397 +    case Bytecodes::_dstore:
   1.398 +      pop_pair_local(iter()->get_index());
   1.399 +      break;
   1.400 +
   1.401 +    case Bytecodes::_pop:
   1.402 +      pop();
   1.403 +      break;
   1.404 +    case Bytecodes::_pop2:
   1.405 +      pop();
   1.406 +      pop();
   1.407 +      break;
   1.408 +    case Bytecodes::_swap:
   1.409 +      a = pop();
   1.410 +      b = pop();
   1.411 +      push(a);
   1.412 +      push(b);
   1.413 +      break;
   1.414 +    case Bytecodes::_dup:
   1.415 +      a = pop();
   1.416 +      push(a);
   1.417 +      push(a);
   1.418 +      break;
   1.419 +    case Bytecodes::_dup_x1:
   1.420 +      a = pop();
   1.421 +      b = pop();
   1.422 +      push(a);
   1.423 +      push(b);
   1.424 +      push(a);
   1.425 +      break;
   1.426 +    case Bytecodes::_dup_x2:
   1.427 +      a = pop();
   1.428 +      b = pop();
   1.429 +      c = pop();
   1.430 +      push(a);
   1.431 +      push(c);
   1.432 +      push(b);
   1.433 +      push(a);
   1.434 +      break;
   1.435 +    case Bytecodes::_dup2:
   1.436 +      a = pop();
   1.437 +      b = pop();
   1.438 +      push(b);
   1.439 +      push(a);
   1.440 +      push(b);
   1.441 +      push(a);
   1.442 +      break;
   1.443 +    case Bytecodes::_dup2_x1:
   1.444 +      a = pop();
   1.445 +      b = pop();
   1.446 +      c = pop();
   1.447 +      push(b);
   1.448 +      push(a);
   1.449 +      push(c);
   1.450 +      push(b);
   1.451 +      push(a);
   1.452 +      break;
   1.453 +    case Bytecodes::_dup2_x2:
   1.454 +      a = pop();
   1.455 +      b = pop();
   1.456 +      c = pop();
   1.457 +      d = pop();
   1.458 +      push(b);
   1.459 +      push(a);
   1.460 +      push(d);
   1.461 +      push(c);
   1.462 +      push(b);
   1.463 +      push(a);
   1.464 +      break;
   1.465 +
   1.466 +    case Bytecodes::_getfield:
   1.467 +      if (!do_getfield())
   1.468 +        return false;
   1.469 +      break;
   1.470 +    case Bytecodes::_getstatic:
   1.471 +      if (!do_getstatic())
   1.472 +        return false;
   1.473 +      break;
   1.474 +    case Bytecodes::_putfield:
   1.475 +      if (!do_putfield())
   1.476 +        return false;
   1.477 +      break;
   1.478 +
   1.479 +    case Bytecodes::_iadd:
   1.480 +    case Bytecodes::_isub:
   1.481 +    case Bytecodes::_imul:
   1.482 +    case Bytecodes::_iand:
   1.483 +    case Bytecodes::_ixor:
   1.484 +    case Bytecodes::_ishl:
   1.485 +    case Bytecodes::_ishr:
   1.486 +    case Bytecodes::_iushr:
   1.487 +      pop();
   1.488 +      pop();
   1.489 +      push(false);
   1.490 +      break;
   1.491 +    case Bytecodes::_ior:
   1.492 +      a = pop();
   1.493 +      b = pop();
   1.494 +      push(a && b);
   1.495 +      break;
   1.496 +    case Bytecodes::_idiv:
   1.497 +    case Bytecodes::_irem:
   1.498 +      if (!pop())
   1.499 +        return false;
   1.500 +      pop();
   1.501 +      push(false);
   1.502 +      break;
   1.503 +    case Bytecodes::_ineg:
   1.504 +      break;
   1.505 +
   1.506 +    case Bytecodes::_ladd:
   1.507 +    case Bytecodes::_lsub:
   1.508 +    case Bytecodes::_lmul:
   1.509 +    case Bytecodes::_land:
   1.510 +    case Bytecodes::_lxor:
   1.511 +      pop();
   1.512 +      pop();
   1.513 +      pop();
   1.514 +      pop();
   1.515 +      push(false);
   1.516 +      push(false);
   1.517 +      break;
   1.518 +    case Bytecodes::_lor:
   1.519 +      a = pop();
   1.520 +      b = pop();
   1.521 +      push(a && b);
   1.522 +      break;
   1.523 +    case Bytecodes::_ldiv:
   1.524 +    case Bytecodes::_lrem:
   1.525 +      pop();
   1.526 +      if (!pop())
   1.527 +        return false;
   1.528 +      pop();
   1.529 +      pop();
   1.530 +      push(false);
   1.531 +      push(false);
   1.532 +      break;
   1.533 +    case Bytecodes::_lneg:
   1.534 +      break;
   1.535 +    case Bytecodes::_lshl:
   1.536 +    case Bytecodes::_lshr:
   1.537 +    case Bytecodes::_lushr:
   1.538 +      pop();
   1.539 +      pop();
   1.540 +      pop();
   1.541 +      push(false);
   1.542 +      push(false);
   1.543 +      break;
   1.544 +
   1.545 +    case Bytecodes::_fadd:
   1.546 +    case Bytecodes::_fsub:
   1.547 +    case Bytecodes::_fmul:
   1.548 +    case Bytecodes::_fdiv:
   1.549 +    case Bytecodes::_frem:
   1.550 +      pop();
   1.551 +      pop();
   1.552 +      push(false);
   1.553 +      break;
   1.554 +    case Bytecodes::_fneg:
   1.555 +      break;
   1.556 +
   1.557 +    case Bytecodes::_dadd:
   1.558 +    case Bytecodes::_dsub:
   1.559 +    case Bytecodes::_dmul:
   1.560 +    case Bytecodes::_ddiv:
   1.561 +    case Bytecodes::_drem:
   1.562 +      pop();
   1.563 +      pop();
   1.564 +      pop();
   1.565 +      pop();
   1.566 +      push(false);
   1.567 +      push(false);
   1.568 +      break;
   1.569 +    case Bytecodes::_dneg:
   1.570 +      break;
   1.571 +
   1.572 +    case Bytecodes::_iinc:
   1.573 +      set_local(iter()->get_index(), false);
   1.574 +      break;
   1.575 +
   1.576 +    case Bytecodes::_lcmp:
   1.577 +      pop();
   1.578 +      pop();
   1.579 +      pop();
   1.580 +      pop();
   1.581 +      push(false);
   1.582 +      break;
   1.583 +
   1.584 +    case Bytecodes::_fcmpl:
   1.585 +    case Bytecodes::_fcmpg:
   1.586 +      pop();
   1.587 +      pop();
   1.588 +      push(false);
   1.589 +      break;
   1.590 +
   1.591 +    case Bytecodes::_dcmpl:
   1.592 +    case Bytecodes::_dcmpg:
   1.593 +      pop();
   1.594 +      pop();
   1.595 +      pop();
   1.596 +      pop();
   1.597 +      push(false);
   1.598 +      break;
   1.599 +
   1.600 +    case Bytecodes::_i2l:
   1.601 +      push(false);
   1.602 +      break;
   1.603 +    case Bytecodes::_i2f:
   1.604 +      pop();
   1.605 +      push(false);
   1.606 +      break;
   1.607 +    case Bytecodes::_i2d:
   1.608 +      pop();
   1.609 +      push(false);
   1.610 +      push(false);
   1.611 +      break;
   1.612 +
   1.613 +    case Bytecodes::_l2i:
   1.614 +    case Bytecodes::_l2f:
   1.615 +      pop();
   1.616 +      pop();
   1.617 +      push(false);
   1.618 +      break;
   1.619 +    case Bytecodes::_l2d:
   1.620 +      pop();
   1.621 +      pop();
   1.622 +      push(false);
   1.623 +      push(false);
   1.624 +      break;
   1.625 +
   1.626 +    case Bytecodes::_f2i:
   1.627 +      pop();
   1.628 +      push(false);
   1.629 +      break;
   1.630 +    case Bytecodes::_f2l:
   1.631 +    case Bytecodes::_f2d:
   1.632 +      pop();
   1.633 +      push(false);
   1.634 +      push(false);
   1.635 +      break;
   1.636 +
   1.637 +    case Bytecodes::_d2i:
   1.638 +    case Bytecodes::_d2f:
   1.639 +      pop();
   1.640 +      pop();
   1.641 +      push(false);
   1.642 +      break;
   1.643 +    case Bytecodes::_d2l:
   1.644 +      pop();
   1.645 +      pop();
   1.646 +      push(false);
   1.647 +      push(false);
   1.648 +      break;
   1.649 +
   1.650 +    case Bytecodes::_i2b:
   1.651 +    case Bytecodes::_i2c:
   1.652 +    case Bytecodes::_i2s:
   1.653 +      pop();
   1.654 +      push(false);
   1.655 +      break;
   1.656 +
   1.657 +    case Bytecodes::_return:
   1.658 +    case Bytecodes::_ireturn:
   1.659 +    case Bytecodes::_lreturn:
   1.660 +    case Bytecodes::_freturn:
   1.661 +    case Bytecodes::_dreturn:
   1.662 +    case Bytecodes::_areturn:
   1.663 +      break;
   1.664 +
   1.665 +    default:
   1.666 +      return false;
   1.667 +    }
   1.668 +  }
   1.669 +
   1.670 +  return true;
   1.671 +}
   1.672 +
   1.673 +void SharkInlinerHelper::initialize_for_check() {
   1.674 +  _locals = NEW_RESOURCE_ARRAY(bool, max_locals());
   1.675 +  _stack = NEW_RESOURCE_ARRAY(bool, max_stack());
   1.676 +
   1.677 +  memset(_locals, 0, max_locals() * sizeof(bool));
   1.678 +  for (int i = 0; i < target()->arg_size(); i++) {
   1.679 +    SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i);
   1.680 +    if (arg && arg->zero_checked())
   1.681 +      set_local(i, true);
   1.682 +  }
   1.683 +
   1.684 +  _sp = _stack;
   1.685 +}
   1.686 +
   1.687 +bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
   1.688 +  assert(is_get || is_field, "can't inline putstatic");
   1.689 +
   1.690 +  // If the holder isn't linked then there isn't a lot we can do
   1.691 +  if (!target()->holder()->is_linked())
   1.692 +    return false;
   1.693 +
   1.694 +  // Get the field
   1.695 +  bool will_link;
   1.696 +  ciField *field = iter()->get_field(will_link);
   1.697 +  if (!will_link)
   1.698 +    return false;
   1.699 +
   1.700 +  // If the field is mismatched then an exception needs throwing
   1.701 +  if (is_field == field->is_static())
   1.702 +    return false;
   1.703 +
   1.704 +  // Pop the value off the stack if necessary
   1.705 +  if (!is_get) {
   1.706 +    pop();
   1.707 +    if (field->type()->is_two_word())
   1.708 +      pop();
   1.709 +  }
   1.710 +
   1.711 +  // Pop and null-check the receiver if necessary
   1.712 +  if (is_field) {
   1.713 +    if (!pop())
   1.714 +      return false;
   1.715 +  }
   1.716 +
   1.717 +  // Push the result if necessary
   1.718 +  if (is_get) {
   1.719 +    bool result_pushed = false;
   1.720 +    if (field->is_constant()) {
   1.721 +      SharkConstant *sc = SharkConstant::for_field(iter());
   1.722 +      if (sc->is_loaded()) {
   1.723 +        push(sc->is_nonzero());
   1.724 +        result_pushed = true;
   1.725 +      }
   1.726 +    }
   1.727 +
   1.728 +    if (!result_pushed)
   1.729 +      push(false);
   1.730 +
   1.731 +    if (field->type()->is_two_word())
   1.732 +      push(false);
   1.733 +  }
   1.734 +
   1.735 +  return true;
   1.736 +}
   1.737 +
   1.738 +bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
   1.739 +  if (SharkIntrinsics::is_intrinsic(target)) {
   1.740 +    SharkIntrinsics::inline_intrinsic(target, state);
   1.741 +    return true;
   1.742 +  }
   1.743 +
   1.744 +  if (may_be_inlinable(target)) {
   1.745 +    SharkInlinerHelper inliner(target, state);
   1.746 +    if (inliner.is_inlinable()) {
   1.747 +      inliner.do_inline();
   1.748 +      return true;
   1.749 +    }
   1.750 +  }
   1.751 +  return false;
   1.752 +}

mercurial