OLD | NEW |
1 | 1 |
2 // Copyright 2011 the V8 project authors. All rights reserved. | 2 // Copyright 2011 the V8 project authors. All rights reserved. |
3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
5 | 5 |
6 #include "src/v8.h" | 6 #include "src/v8.h" |
7 | 7 |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen.h" | 10 #include "src/full-codegen.h" |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 | 317 |
318 | 318 |
319 // Maximum size of a table entry generated below. | 319 // Maximum size of a table entry generated below. |
320 const int Deoptimizer::table_entry_size_ = 2 * Assembler::kInstrSize; | 320 const int Deoptimizer::table_entry_size_ = 2 * Assembler::kInstrSize; |
321 | 321 |
322 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { | 322 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { |
323 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); | 323 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); |
324 | 324 |
325 // Create a sequence of deoptimization entries. | 325 // Create a sequence of deoptimization entries. |
326 // Note that registers are still live when jumping to an entry. | 326 // Note that registers are still live when jumping to an entry. |
327 Label table_start, done; | 327 Label table_start, done, done_special, trampoline_jump; |
328 __ bind(&table_start); | 328 __ bind(&table_start); |
329 for (int i = 0; i < count(); i++) { | 329 int kMaxEntriesBranchReach = (1 << (kImm16Bits - 2))/ |
330 Label start; | 330 (table_entry_size_ / Assembler::kInstrSize); |
331 __ bind(&start); | |
332 DCHECK(is_int16(i)); | |
333 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. | |
334 __ li(at, i); // In the delay slot. | |
335 | 331 |
336 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); | 332 if (count() <= kMaxEntriesBranchReach) { |
| 333 // Common case. |
| 334 for (int i = 0; i < count(); i++) { |
| 335 Label start; |
| 336 __ bind(&start); |
| 337 DCHECK(is_int16(i)); |
| 338 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. |
| 339 __ li(at, i); // In the delay slot. |
| 340 |
| 341 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
| 342 } |
| 343 |
| 344 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
| 345 count() * table_entry_size_); |
| 346 __ bind(&done); |
| 347 __ Push(at); |
| 348 } else { |
| 349 // Uncommon case, the branch cannot reach. |
| 350 // Create mini trampoline and adjust id constants to get proper value at |
| 351 // the end of table. |
| 352 for (int i = kMaxEntriesBranchReach; i > 1; i--) { |
| 353 Label start; |
| 354 __ bind(&start); |
| 355 DCHECK(is_int16(i)); |
| 356 __ Branch(USE_DELAY_SLOT, &trampoline_jump); // Expose delay slot. |
| 357 __ li(at, - i); // In the delay slot. |
| 358 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
| 359 } |
| 360 // Entry with id == kMaxEntriesBranchReach - 1. |
| 361 __ bind(&trampoline_jump); |
| 362 __ Branch(USE_DELAY_SLOT, &done_special); |
| 363 __ li(at, -1); |
| 364 |
| 365 for (int i = kMaxEntriesBranchReach ; i < count(); i++) { |
| 366 Label start; |
| 367 __ bind(&start); |
| 368 DCHECK(is_int16(i)); |
| 369 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. |
| 370 __ li(at, i); // In the delay slot. |
| 371 } |
| 372 |
| 373 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
| 374 count() * table_entry_size_); |
| 375 __ bind(&done_special); |
| 376 __ addiu(at, at, kMaxEntriesBranchReach); |
| 377 __ bind(&done); |
| 378 __ Push(at); |
337 } | 379 } |
338 | |
339 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), | |
340 count() * table_entry_size_); | |
341 __ bind(&done); | |
342 __ Push(at); | |
343 } | 380 } |
344 | 381 |
345 | 382 |
346 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { | 383 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { |
347 SetFrameSlot(offset, value); | 384 SetFrameSlot(offset, value); |
348 } | 385 } |
349 | 386 |
350 | 387 |
351 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { | 388 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { |
352 SetFrameSlot(offset, value); | 389 SetFrameSlot(offset, value); |
353 } | 390 } |
354 | 391 |
355 | 392 |
356 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 393 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
357 // No out-of-line constant pool support. | 394 // No out-of-line constant pool support. |
358 UNREACHABLE(); | 395 UNREACHABLE(); |
359 } | 396 } |
360 | 397 |
361 | 398 |
362 #undef __ | 399 #undef __ |
363 | 400 |
364 | 401 |
365 } } // namespace v8::internal | 402 } } // namespace v8::internal |
OLD | NEW |