6187
+ − 1
/*
+ − 2
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ − 3
* Copyright 2008, 2009 Red Hat, Inc.
+ − 4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ − 5
*
+ − 6
* This code is free software; you can redistribute it and/or modify it
+ − 7
* under the terms of the GNU General Public License version 2 only, as
+ − 8
* published by the Free Software Foundation.
+ − 9
*
+ − 10
* This code is distributed in the hope that it will be useful, but WITHOUT
+ − 11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 13
* version 2 for more details (a copy is included in the LICENSE file that
+ − 14
* accompanied this code).
+ − 15
*
+ − 16
* You should have received a copy of the GNU General Public License version
+ − 17
* 2 along with this work; if not, write to the Free Software Foundation,
+ − 18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ − 19
*
+ − 20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ − 21
* or visit www.oracle.com if you need additional information or have any
+ − 22
* questions.
+ − 23
*
+ − 24
*/
+ − 25
+ − 26
// Class hierarchy:
+ − 27
// - SharkStateScanner
+ − 28
// - SharkCacherDecacher
+ − 29
// - SharkDecacher
+ − 30
// - SharkJavaCallDecacher
+ − 31
// - SharkVMCallDecacher
+ − 32
// - SharkTrapDecacher
+ − 33
// - SharkCacher
+ − 34
// - SharkJavaCallCacher
+ − 35
// - SharkVMCallCacher
+ − 36
// - SharkFunctionEntryCacher
+ − 37
// - SharkNormalEntryCacher
+ − 38
// - SharkOSREntryCacher
+ − 39
+ − 40
class SharkCacherDecacher : public SharkStateScanner {
+ − 41
protected:
+ − 42
SharkCacherDecacher(SharkFunction* function)
+ − 43
: SharkStateScanner(function) {}
+ − 44
+ − 45
// Helper
+ − 46
protected:
+ − 47
static int adjusted_offset(SharkValue* value, int offset) {
+ − 48
if (value->is_two_word())
+ − 49
offset--;
+ − 50
return offset;
+ − 51
}
+ − 52
};
+ − 53
+ − 54
class SharkDecacher : public SharkCacherDecacher {
+ − 55
protected:
+ − 56
SharkDecacher(SharkFunction* function, int bci)
+ − 57
: SharkCacherDecacher(function), _bci(bci) {}
+ − 58
+ − 59
private:
+ − 60
int _bci;
+ − 61
+ − 62
protected:
+ − 63
int bci() const {
+ − 64
return _bci;
+ − 65
}
+ − 66
+ − 67
private:
+ − 68
int _pc_offset;
+ − 69
OopMap* _oopmap;
+ − 70
GrowableArray<ScopeValue*>* _exparray;
+ − 71
GrowableArray<MonitorValue*>* _monarray;
+ − 72
GrowableArray<ScopeValue*>* _locarray;
+ − 73
+ − 74
private:
+ − 75
int pc_offset() const {
+ − 76
return _pc_offset;
+ − 77
}
+ − 78
OopMap* oopmap() const {
+ − 79
return _oopmap;
+ − 80
}
+ − 81
GrowableArray<ScopeValue*>* exparray() const {
+ − 82
return _exparray;
+ − 83
}
+ − 84
GrowableArray<MonitorValue*>* monarray() const {
+ − 85
return _monarray;
+ − 86
}
+ − 87
GrowableArray<ScopeValue*>* locarray() const {
+ − 88
return _locarray;
+ − 89
}
+ − 90
+ − 91
// Callbacks
+ − 92
protected:
+ − 93
void start_frame();
+ − 94
+ − 95
void start_stack(int stack_depth);
+ − 96
void process_stack_slot(int index, SharkValue** value, int offset);
+ − 97
+ − 98
void start_monitors(int num_monitors);
+ − 99
void process_monitor(int index, int box_offset, int obj_offset);
+ − 100
+ − 101
void process_oop_tmp_slot(llvm::Value** value, int offset);
+ − 102
void process_method_slot(llvm::Value** value, int offset);
+ − 103
void process_pc_slot(int offset);
+ − 104
+ − 105
void start_locals();
+ − 106
void process_local_slot(int index, SharkValue** value, int offset);
+ − 107
+ − 108
void end_frame();
+ − 109
+ − 110
// oopmap and debuginfo helpers
+ − 111
private:
+ − 112
static int oopmap_slot_munge(int offset) {
+ − 113
return SharkStack::oopmap_slot_munge(offset);
+ − 114
}
+ − 115
static VMReg slot2reg(int offset) {
+ − 116
return SharkStack::slot2reg(offset);
+ − 117
}
+ − 118
static Location slot2loc(int offset, Location::Type type) {
+ − 119
return Location::new_stk_loc(type, offset * wordSize);
+ − 120
}
+ − 121
static LocationValue* slot2lv(int offset, Location::Type type) {
+ − 122
return new LocationValue(slot2loc(offset, type));
+ − 123
}
+ − 124
static Location::Type location_type(SharkValue** addr, bool maybe_two_word) {
+ − 125
// low addresses this end
+ − 126
// Type 32-bit 64-bit
+ − 127
// ----------------------------------------------------
+ − 128
// stack[0] local[3] jobject oop oop
+ − 129
// stack[1] local[2] NULL normal lng
+ − 130
// stack[2] local[1] jlong normal invalid
+ − 131
// stack[3] local[0] jint normal normal
+ − 132
//
+ − 133
// high addresses this end
+ − 134
+ − 135
SharkValue *value = *addr;
+ − 136
if (value) {
+ − 137
if (value->is_jobject())
+ − 138
return Location::oop;
+ − 139
#ifdef _LP64
+ − 140
if (value->is_two_word())
+ − 141
return Location::invalid;
+ − 142
#endif // _LP64
+ − 143
return Location::normal;
+ − 144
}
+ − 145
else {
+ − 146
if (maybe_two_word) {
+ − 147
value = *(addr - 1);
+ − 148
if (value && value->is_two_word()) {
+ − 149
#ifdef _LP64
+ − 150
if (value->is_jlong())
+ − 151
return Location::lng;
+ − 152
if (value->is_jdouble())
+ − 153
return Location::dbl;
+ − 154
ShouldNotReachHere();
+ − 155
#else
+ − 156
return Location::normal;
+ − 157
#endif // _LP64
+ − 158
}
+ − 159
}
+ − 160
return Location::invalid;
+ − 161
}
+ − 162
}
+ − 163
+ − 164
// Stack slot helpers
+ − 165
protected:
+ − 166
virtual bool stack_slot_needs_write(int index, SharkValue* value) = 0;
+ − 167
virtual bool stack_slot_needs_oopmap(int index, SharkValue* value) = 0;
+ − 168
virtual bool stack_slot_needs_debuginfo(int index, SharkValue* value) = 0;
+ − 169
+ − 170
static Location::Type stack_location_type(int index, SharkValue** addr) {
+ − 171
return location_type(addr, *addr == NULL);
+ − 172
}
+ − 173
+ − 174
// Local slot helpers
+ − 175
protected:
+ − 176
virtual bool local_slot_needs_write(int index, SharkValue* value) = 0;
+ − 177
virtual bool local_slot_needs_oopmap(int index, SharkValue* value) = 0;
+ − 178
virtual bool local_slot_needs_debuginfo(int index, SharkValue* value) = 0;
+ − 179
+ − 180
static Location::Type local_location_type(int index, SharkValue** addr) {
+ − 181
return location_type(addr, index > 0);
+ − 182
}
+ − 183
+ − 184
// Writer helper
+ − 185
protected:
+ − 186
void write_value_to_frame(const llvm::Type* type,
+ − 187
llvm::Value* value,
+ − 188
int offset);
+ − 189
};
+ − 190
+ − 191
class SharkJavaCallDecacher : public SharkDecacher {
+ − 192
public:
+ − 193
SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee)
+ − 194
: SharkDecacher(function, bci), _callee(callee) {}
+ − 195
+ − 196
private:
+ − 197
ciMethod* _callee;
+ − 198
+ − 199
protected:
+ − 200
ciMethod* callee() const {
+ − 201
return _callee;
+ − 202
}
+ − 203
+ − 204
// Stack slot helpers
+ − 205
protected:
+ − 206
bool stack_slot_needs_write(int index, SharkValue* value) {
+ − 207
return value && (index < callee()->arg_size() || value->is_jobject());
+ − 208
}
+ − 209
bool stack_slot_needs_oopmap(int index, SharkValue* value) {
+ − 210
return value && value->is_jobject() && index >= callee()->arg_size();
+ − 211
}
+ − 212
bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
+ − 213
return index >= callee()->arg_size();
+ − 214
}
+ − 215
+ − 216
// Local slot helpers
+ − 217
protected:
+ − 218
bool local_slot_needs_write(int index, SharkValue* value) {
+ − 219
return value && value->is_jobject();
+ − 220
}
+ − 221
bool local_slot_needs_oopmap(int index, SharkValue* value) {
+ − 222
return value && value->is_jobject();
+ − 223
}
+ − 224
bool local_slot_needs_debuginfo(int index, SharkValue* value) {
+ − 225
return true;
+ − 226
}
+ − 227
};
+ − 228
+ − 229
class SharkVMCallDecacher : public SharkDecacher {
+ − 230
public:
+ − 231
SharkVMCallDecacher(SharkFunction* function, int bci)
+ − 232
: SharkDecacher(function, bci) {}
+ − 233
+ − 234
// Stack slot helpers
+ − 235
protected:
+ − 236
bool stack_slot_needs_write(int index, SharkValue* value) {
+ − 237
return value && value->is_jobject();
+ − 238
}
+ − 239
bool stack_slot_needs_oopmap(int index, SharkValue* value) {
+ − 240
return value && value->is_jobject();
+ − 241
}
+ − 242
bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
+ − 243
return true;
+ − 244
}
+ − 245
+ − 246
// Local slot helpers
+ − 247
protected:
+ − 248
bool local_slot_needs_write(int index, SharkValue* value) {
+ − 249
return value && value->is_jobject();
+ − 250
}
+ − 251
bool local_slot_needs_oopmap(int index, SharkValue* value) {
+ − 252
return value && value->is_jobject();
+ − 253
}
+ − 254
bool local_slot_needs_debuginfo(int index, SharkValue* value) {
+ − 255
return true;
+ − 256
}
+ − 257
};
+ − 258
+ − 259
class SharkTrapDecacher : public SharkDecacher {
+ − 260
public:
+ − 261
SharkTrapDecacher(SharkFunction* function, int bci)
+ − 262
: SharkDecacher(function, bci) {}
+ − 263
+ − 264
// Stack slot helpers
+ − 265
protected:
+ − 266
bool stack_slot_needs_write(int index, SharkValue* value) {
+ − 267
return value != NULL;
+ − 268
}
+ − 269
bool stack_slot_needs_oopmap(int index, SharkValue* value) {
+ − 270
return value && value->is_jobject();
+ − 271
}
+ − 272
bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
+ − 273
return true;
+ − 274
}
+ − 275
+ − 276
// Local slot helpers
+ − 277
protected:
+ − 278
bool local_slot_needs_write(int index, SharkValue* value) {
+ − 279
return value != NULL;
+ − 280
}
+ − 281
bool local_slot_needs_oopmap(int index, SharkValue* value) {
+ − 282
return value && value->is_jobject();
+ − 283
}
+ − 284
bool local_slot_needs_debuginfo(int index, SharkValue* value) {
+ − 285
return true;
+ − 286
}
+ − 287
};
+ − 288
+ − 289
class SharkCacher : public SharkCacherDecacher {
+ − 290
protected:
+ − 291
SharkCacher(SharkFunction* function)
+ − 292
: SharkCacherDecacher(function) {}
+ − 293
+ − 294
// Callbacks
+ − 295
protected:
+ − 296
void process_stack_slot(int index, SharkValue** value, int offset);
+ − 297
+ − 298
void process_oop_tmp_slot(llvm::Value** value, int offset);
+ − 299
virtual void process_method_slot(llvm::Value** value, int offset);
+ − 300
+ − 301
virtual void process_local_slot(int index, SharkValue** value, int offset);
+ − 302
+ − 303
// Stack slot helper
+ − 304
protected:
+ − 305
virtual bool stack_slot_needs_read(int index, SharkValue* value) = 0;
+ − 306
+ − 307
// Local slot helper
+ − 308
protected:
+ − 309
virtual bool local_slot_needs_read(int index, SharkValue* value) {
+ − 310
return value && value->is_jobject();
+ − 311
}
+ − 312
+ − 313
// Writer helper
+ − 314
protected:
+ − 315
llvm::Value* read_value_from_frame(const llvm::Type* type, int offset);
+ − 316
};
+ − 317
+ − 318
class SharkJavaCallCacher : public SharkCacher {
+ − 319
public:
+ − 320
SharkJavaCallCacher(SharkFunction* function, ciMethod* callee)
+ − 321
: SharkCacher(function), _callee(callee) {}
+ − 322
+ − 323
private:
+ − 324
ciMethod* _callee;
+ − 325
+ − 326
protected:
+ − 327
ciMethod* callee() const {
+ − 328
return _callee;
+ − 329
}
+ − 330
+ − 331
// Stack slot helper
+ − 332
protected:
+ − 333
bool stack_slot_needs_read(int index, SharkValue* value) {
+ − 334
return value && (index < callee()->return_type()->size() ||
+ − 335
value->is_jobject());
+ − 336
}
+ − 337
};
+ − 338
+ − 339
class SharkVMCallCacher : public SharkCacher {
+ − 340
public:
+ − 341
SharkVMCallCacher(SharkFunction* function)
+ − 342
: SharkCacher(function) {}
+ − 343
+ − 344
// Stack slot helper
+ − 345
protected:
+ − 346
bool stack_slot_needs_read(int index, SharkValue* value) {
+ − 347
return value && value->is_jobject();
+ − 348
}
+ − 349
};
+ − 350
+ − 351
class SharkFunctionEntryCacher : public SharkCacher {
+ − 352
public:
+ − 353
SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method)
+ − 354
: SharkCacher(function), _method(method) {}
+ − 355
+ − 356
private:
+ − 357
llvm::Value* _method;
+ − 358
+ − 359
private:
+ − 360
llvm::Value* method() const {
+ − 361
return _method;
+ − 362
}
+ − 363
+ − 364
// Method slot callback
+ − 365
protected:
+ − 366
void process_method_slot(llvm::Value** value, int offset);
+ − 367
+ − 368
// Stack slot helper
+ − 369
protected:
+ − 370
bool stack_slot_needs_read(int index, SharkValue* value) {
+ − 371
ShouldNotReachHere(); // entry block shouldn't have stack
+ − 372
}
+ − 373
+ − 374
// Local slot helper
+ − 375
protected:
+ − 376
bool local_slot_needs_read(int index, SharkValue* value) {
+ − 377
return value != NULL;
+ − 378
}
+ − 379
};
+ − 380
+ − 381
class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
+ − 382
public:
+ − 383
SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
+ − 384
: SharkFunctionEntryCacher(function, method) {}
+ − 385
};
+ − 386
+ − 387
class SharkOSREntryCacher : public SharkFunctionEntryCacher {
+ − 388
public:
+ − 389
SharkOSREntryCacher(SharkFunction* function,
+ − 390
llvm::Value* method,
+ − 391
llvm::Value* osr_buf)
+ − 392
: SharkFunctionEntryCacher(function, method),
+ − 393
_osr_buf(
+ − 394
builder()->CreateBitCast(
+ − 395
osr_buf,
+ − 396
llvm::PointerType::getUnqual(
+ − 397
llvm::ArrayType::get(
+ − 398
SharkType::intptr_type(),
+ − 399
max_locals() + max_monitors() * 2)))) {}
+ − 400
+ − 401
private:
+ − 402
llvm::Value* _osr_buf;
+ − 403
+ − 404
private:
+ − 405
llvm::Value* osr_buf() const {
+ − 406
return _osr_buf;
+ − 407
}
+ − 408
+ − 409
// Callbacks
+ − 410
protected:
+ − 411
void process_monitor(int index, int box_offset, int obj_offset);
+ − 412
void process_local_slot(int index, SharkValue** value, int offset);
+ − 413
+ − 414
// Helper
+ − 415
private:
+ − 416
llvm::Value* CreateAddressOfOSRBufEntry(int offset, const llvm::Type* type);
+ − 417
};