hotspot/src/share/vm/asm/assembler.cpp
author coleenp
Mon, 14 Jan 2013 11:01:39 -0500
changeset 15194 a35093d73168
parent 14837 a75c3082d106
child 16368 713209c45a82
permissions -rw-r--r--
8006005: Fix constant pool index validation and alignment trap for method parameter reflection Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data. Reviewed-by: jrose, dholmes Contributed-by: eric.mccorkle@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
13963
e5b53c306fb5 7197424: update copyright year to match last edit in jdk8 hotspot repository
mikael
parents: 13391
diff changeset
     2
 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5403
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5403
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5403
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    25
#include "precompiled.hpp"
14626
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14625
diff changeset
    26
#include "asm/macroAssembler.hpp"
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14625
diff changeset
    27
#include "asm/macroAssembler.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    28
#include "asm/codeBuffer.hpp"
14626
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14625
diff changeset
    29
#include "runtime/atomic.hpp"
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14625
diff changeset
    30
#include "runtime/atomic.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    31
#include "runtime/icache.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 5547
diff changeset
    32
#include "runtime/os.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
// Implementation of AbstractAssembler
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
// The AbstractAssembler is generating code into a CodeBuffer. To make code generation faster,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
// the assembler keeps a copy of the code buffers boundaries & modifies them when
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
// emitting bytes rather than using the code buffers accessor functions all the time.
2131
98f9cef66a34 6810672: Comment typos
twisti
parents: 1412
diff changeset
    40
// The code buffer is updated via set_code_end(...) after emitting a whole instruction.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
AbstractAssembler::AbstractAssembler(CodeBuffer* code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  if (code == NULL)  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
  CodeSection* cs = code->insts();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  cs->clear_mark();   // new assembler kills old mark
14625
b02f361c324e 8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents: 14624
diff changeset
    46
  if (cs->start() == NULL)  {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 3261
diff changeset
    47
    vm_exit_out_of_memory(0, err_msg("CodeCache: no room for %s",
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 3261
diff changeset
    48
                                     code->name()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  }
14625
b02f361c324e 8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents: 14624
diff changeset
    50
  _code_section = cs;
b02f361c324e 8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents: 14624
diff changeset
    51
  _oop_recorder= code->oop_recorder();
b02f361c324e 8003195: AbstractAssembler should not store code pointers but use the CodeSection directly
twisti
parents: 14624
diff changeset
    52
  DEBUG_ONLY( _short_branch_delta = 0; )
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
void AbstractAssembler::set_code_section(CodeSection* cs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  assert(cs->outer() == code_section()->outer(), "sanity");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  assert(cs->is_allocated(), "need to pre-allocate this section");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  cs->clear_mark();  // new assembly into this section kills old mark
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  _code_section = cs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
// Inform CodeBuffer that incoming code and relocation will be for stubs
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
address AbstractAssembler::start_a_stub(int required_space) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  CodeBuffer*  cb = code();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  CodeSection* cs = cb->stubs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  assert(_code_section == cb->insts(), "not in insts?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  if (cs->maybe_expand_to_ensure_remaining(required_space)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
      && cb->blob() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  set_code_section(cs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  return pc();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
// Inform CodeBuffer that incoming code and relocation will be code
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
// Should not be called if start_a_stub() returned NULL
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
void AbstractAssembler::end_a_stub() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  assert(_code_section == code()->stubs(), "not in stubs?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  set_code_section(code()->insts());
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
// Inform CodeBuffer that incoming code and relocation will be for stubs
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
address AbstractAssembler::start_a_const(int required_space, int required_align) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  CodeBuffer*  cb = code();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  CodeSection* cs = cb->consts();
14624
8f5ec8cfe196 8003850: add support for constants in stub code
kvn
parents: 13963
diff changeset
    86
  assert(_code_section == cb->insts() || _code_section == cb->stubs(), "not in insts/stubs?");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  address end = cs->end();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  int pad = -(intptr_t)end & (required_align-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  if (cs->maybe_expand_to_ensure_remaining(pad + required_space)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
    if (cb->blob() == NULL)  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
    end = cs->end();  // refresh pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  if (pad > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
    while (--pad >= 0) { *end++ = 0; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
    cs->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
  set_code_section(cs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  return end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
// Inform CodeBuffer that incoming code and relocation will be code
14624
8f5ec8cfe196 8003850: add support for constants in stub code
kvn
parents: 13963
diff changeset
   102
// in section cs (insts or stubs).
8f5ec8cfe196 8003850: add support for constants in stub code
kvn
parents: 13963
diff changeset
   103
void AbstractAssembler::end_a_const(CodeSection* cs) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  assert(_code_section == code()->consts(), "not in consts?");
14624
8f5ec8cfe196 8003850: add support for constants in stub code
kvn
parents: 13963
diff changeset
   105
  set_code_section(cs);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
void AbstractAssembler::flush() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  ICache::invalidate_range(addr_at(0), offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
void AbstractAssembler::bind(Label& L) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  if (L.is_bound()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    // Assembler can bind a label more than once to the same place.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
    guarantee(L.loc() == locator(), "attempt to redefine label");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  L.bind_loc(locator());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  L.patch_instructions((MacroAssembler*)this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
void AbstractAssembler::generate_stack_overflow_check( int frame_size_in_bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  if (UseStackBanging) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    // Each code entry causes one stack bang n pages down the stack where n
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    // is configurable by StackBangPages.  The setting depends on the maximum
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
    // depth of VM call stack or native before going back into java code,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    // since only java code can raise a stack overflow exception using the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    // stack banging mechanism.  The VM and native code does not detect stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    // overflow.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    // The code in JavaCalls::call() checks that there is at least n pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
    // available, so all entry code needs to do is bang once for the end of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
    // this shadow zone.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
    // The entry code may need to bang additional pages if the framesize
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
    // is greater than a page.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    const int page_size = os::vm_page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    int bang_end = StackShadowPages*page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    // This is how far the previous frame's stack banging extended.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    const int bang_end_safe = bang_end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    if (frame_size_in_bytes > page_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
      bang_end += frame_size_in_bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
    int bang_offset = bang_end_safe;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    while (bang_offset <= bang_end) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      // Need at least one stack bang at end of shadow zone.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      bang_stack_with_offset(bang_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      bang_offset += page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  } // end (UseStackBanging)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
void Label::add_patch_at(CodeBuffer* cb, int branch_loc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  assert(_loc == -1, "Label is unbound");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  if (_patch_index < PatchCacheSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    _patches[_patch_index] = branch_loc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    if (_patch_overflow == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
      _patch_overflow = cb->create_patch_overflow();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    _patch_overflow->push(branch_loc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  ++_patch_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
void Label::patch_instructions(MacroAssembler* masm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  assert(is_bound(), "Label is bound");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  CodeBuffer* cb = masm->code();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  int target_sect = CodeBuffer::locator_sect(loc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  address target = cb->locator_address(loc());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  while (_patch_index > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    --_patch_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    int branch_loc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
    if (_patch_index >= PatchCacheSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
      branch_loc = _patch_overflow->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
      branch_loc = _patches[_patch_index];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    int branch_sect = CodeBuffer::locator_sect(branch_loc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    address branch = cb->locator_address(branch_loc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    if (branch_sect == CodeBuffer::SECT_CONSTS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
      // The thing to patch is a constant word.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
      *(address*)branch = target;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
      continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    // Cross-section branches only work if the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
    // intermediate section boundaries are frozen.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
    if (target_sect != branch_sect) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
      for (int n = MIN2(target_sect, branch_sect),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
               nlimit = (target_sect + branch_sect) - n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
           n < nlimit; n++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
        CodeSection* cs = cb->code_section(n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
        assert(cs->is_frozen(), "cross-section branch needs stable offsets");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
#endif //ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
    // Push the target offset into the branch instruction.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
    masm->pd_patch_instruction(branch, target);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   207
struct DelayedConstant {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   208
  typedef void (*value_fn_t)();
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   209
  BasicType type;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   210
  intptr_t value;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   211
  value_fn_t value_fn;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   212
  // This limit of 20 is generous for initial uses.
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   213
  // The limit needs to be large enough to store the field offsets
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   214
  // into classes which do not have statically fixed layouts.
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   215
  // (Initial use is for method handle object offsets.)
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   216
  // Look for uses of "delayed_value" in the source code
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   217
  // and make sure this number is generous enough to handle all of them.
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   218
  enum { DC_LIMIT = 20 };
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   219
  static DelayedConstant delayed_constants[DC_LIMIT];
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   220
  static DelayedConstant* add(BasicType type, value_fn_t value_fn);
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   221
  bool match(BasicType t, value_fn_t cfn) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   222
    return type == t && value_fn == cfn;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   223
  }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   224
  static void update_all();
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   225
};
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   226
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   227
DelayedConstant DelayedConstant::delayed_constants[DC_LIMIT];
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   228
// Default C structure initialization rules have the following effect here:
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   229
// = { { (BasicType)0, (intptr_t)NULL }, ... };
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   230
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   231
DelayedConstant* DelayedConstant::add(BasicType type,
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   232
                                      DelayedConstant::value_fn_t cfn) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   233
  for (int i = 0; i < DC_LIMIT; i++) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   234
    DelayedConstant* dcon = &delayed_constants[i];
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   235
    if (dcon->match(type, cfn))
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   236
      return dcon;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   237
    if (dcon->value_fn == NULL) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   238
      // (cmpxchg not because this is multi-threaded but because I'm paranoid)
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   239
      if (Atomic::cmpxchg_ptr(CAST_FROM_FN_PTR(void*, cfn), &dcon->value_fn, NULL) == NULL) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   240
        dcon->type = type;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   241
        return dcon;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   242
      }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   243
    }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   244
  }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   245
  // If this assert is hit (in pre-integration testing!) then re-evaluate
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   246
  // the comment on the definition of DC_LIMIT.
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   247
  guarantee(false, "too many delayed constants");
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   248
  return NULL;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   249
}
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   250
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   251
void DelayedConstant::update_all() {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   252
  for (int i = 0; i < DC_LIMIT; i++) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   253
    DelayedConstant* dcon = &delayed_constants[i];
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   254
    if (dcon->value_fn != NULL && dcon->value == 0) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   255
      typedef int     (*int_fn_t)();
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   256
      typedef address (*address_fn_t)();
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   257
      switch (dcon->type) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   258
      case T_INT:     dcon->value = (intptr_t) ((int_fn_t)    dcon->value_fn)(); break;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   259
      case T_ADDRESS: dcon->value = (intptr_t) ((address_fn_t)dcon->value_fn)(); break;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   260
      }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   261
    }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   262
  }
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   263
}
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   264
13391
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   265
RegisterOrConstant AbstractAssembler::delayed_value(int(*value_fn)(), Register tmp, int offset) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   266
  intptr_t val = (intptr_t) (*value_fn)();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   267
  if (val != 0)  return val + offset;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   268
  return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   269
}
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   270
RegisterOrConstant AbstractAssembler::delayed_value(address(*value_fn)(), Register tmp, int offset) {
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   271
  intptr_t val = (intptr_t) (*value_fn)();
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   272
  if (val != 0)  return val + offset;
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   273
  return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
30245956af37 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 11434
diff changeset
   274
}
2148
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   275
intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   276
  DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn);
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   277
  return &dcon->value;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   278
}
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   279
intptr_t* AbstractAssembler::delayed_value_addr(address(*value_fn)()) {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   280
  DelayedConstant* dcon = DelayedConstant::add(T_ADDRESS, (DelayedConstant::value_fn_t) value_fn);
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   281
  return &dcon->value;
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   282
}
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   283
void AbstractAssembler::update_delayed_values() {
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   284
  DelayedConstant::update_all();
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   285
}
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   286
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   287
09c7f703773b 6812678: macro assembler needs delayed binding of a few constants (for 6655638)
jrose
parents: 2131
diff changeset
   288
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
void AbstractAssembler::block_comment(const char* comment) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
  if (sect() == CodeBuffer::SECT_INSTS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    code_section()->outer()->block_comment(offset(), comment);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   296
bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   297
  // Exception handler checks the nmethod's implicit null checks table
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   298
  // only when this method returns false.
2254
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   299
#ifdef _LP64
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   300
  if (UseCompressedOops && Universe::narrow_oop_base() != NULL) {
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   301
    assert (Universe::heap() != NULL, "java heap should be initialized");
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   302
    // The first page after heap_base is unmapped and
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   303
    // the 'offset' is equal to [heap_base + offset] for
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   304
    // narrow oop implicit null checks.
2254
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   305
    uintptr_t base = (uintptr_t)Universe::narrow_oop_base();
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   306
    if ((uintptr_t)offset >= base) {
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   307
      // Normalize offset for the next check.
2254
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   308
      offset = (intptr_t)(pointer_delta((void*)offset, (void*)base, 1));
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   309
    }
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   310
  }
2254
f13dda645a4b 6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents: 2148
diff changeset
   311
#endif
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   312
  return offset < 0 || os::vm_page_size() <= offset;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 1
diff changeset
   313
}