OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/full-codegen.h" | 9 #include "src/full-codegen.h" |
10 #include "src/safepoint-table.h" | 10 #include "src/safepoint-table.h" |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 __ InitializeRootRegister(); | 322 __ InitializeRootRegister(); |
323 | 323 |
324 __ pop(at); // Get continuation, leave pc on stack. | 324 __ pop(at); // Get continuation, leave pc on stack. |
325 __ pop(ra); | 325 __ pop(ra); |
326 __ Jump(at); | 326 __ Jump(at); |
327 __ stop("Unreachable."); | 327 __ stop("Unreachable."); |
328 } | 328 } |
329 | 329 |
330 | 330 |
331 // Maximum size of a table entry generated below. | 331 // Maximum size of a table entry generated below. |
332 const int Deoptimizer::table_entry_size_ = 11 * Assembler::kInstrSize; | 332 const int Deoptimizer::table_entry_size_ = 2 * Assembler::kInstrSize; |
333 | 333 |
334 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { | 334 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { |
335 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); | 335 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm()); |
336 | 336 |
337 // Create a sequence of deoptimization entries. | 337 // Create a sequence of deoptimization entries. |
338 // Note that registers are still live when jumping to an entry. | 338 // Note that registers are still live when jumping to an entry. |
339 Label table_start; | 339 Label table_start, done, done_special, trampoline_jump; |
340 __ bind(&table_start); | 340 __ bind(&table_start); |
341 for (int i = 0; i < count(); i++) { | 341 int kMaxEntriesBranchReach = |
342 Label start; | 342 (1 << (kImm16Bits - 2)) / (table_entry_size_ / Assembler::kInstrSize); |
343 __ bind(&start); | |
344 __ daddiu(sp, sp, -1 * kPointerSize); | |
345 // Jump over the remaining deopt entries (including this one). | |
346 // This code is always reached by calling Jump, which puts the target (label | |
347 // start) into t9. | |
348 const int remaining_entries = (count() - i) * table_entry_size_; | |
349 __ Daddu(t9, t9, remaining_entries); | |
350 // 'at' was clobbered so we can only load the current entry value here. | |
351 __ li(t8, i); | |
352 __ jr(t9); // Expose delay slot. | |
353 __ sd(t8, MemOperand(sp, 0 * kPointerSize)); // In the delay slot. | |
354 | 343 |
355 // Pad the rest of the code. | 344 if (count() <= kMaxEntriesBranchReach) { |
356 while (table_entry_size_ > (masm()->SizeOfCodeGeneratedSince(&start))) { | 345 // Common case. |
357 __ nop(); | 346 for (int i = 0; i < count(); i++) { |
| 347 Label start; |
| 348 __ bind(&start); |
| 349 DCHECK(is_int16(i)); |
| 350 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. |
| 351 __ li(at, i); // In the delay slot. |
| 352 |
| 353 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
358 } | 354 } |
359 | 355 |
360 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); | 356 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
| 357 count() * table_entry_size_); |
| 358 __ bind(&done); |
| 359 __ Push(at); |
| 360 } else { |
| 361 // Uncommon case, the branch cannot reach. |
| 362 // Create mini trampoline and adjust id constants to get proper value at |
| 363 // the end of table. |
| 364 for (int i = kMaxEntriesBranchReach; i > 1; i--) { |
| 365 Label start; |
| 366 __ bind(&start); |
| 367 DCHECK(is_int16(i)); |
| 368 __ Branch(USE_DELAY_SLOT, &trampoline_jump); // Expose delay slot. |
| 369 __ li(at, -i); // In the delay slot. |
| 370 DCHECK_EQ(table_entry_size_, masm()->SizeOfCodeGeneratedSince(&start)); |
| 371 } |
| 372 // Entry with id == kMaxEntriesBranchReach - 1. |
| 373 __ bind(&trampoline_jump); |
| 374 __ Branch(USE_DELAY_SLOT, &done_special); |
| 375 __ li(at, -1); |
| 376 |
| 377 for (int i = kMaxEntriesBranchReach; i < count(); i++) { |
| 378 Label start; |
| 379 __ bind(&start); |
| 380 DCHECK(is_int16(i)); |
| 381 __ Branch(USE_DELAY_SLOT, &done); // Expose delay slot. |
| 382 __ li(at, i); // In the delay slot. |
| 383 } |
| 384 |
| 385 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), |
| 386 count() * table_entry_size_); |
| 387 __ bind(&done_special); |
| 388 __ daddiu(at, at, kMaxEntriesBranchReach); |
| 389 __ bind(&done); |
| 390 __ Push(at); |
361 } | 391 } |
362 | |
363 DCHECK_EQ(masm()->SizeOfCodeGeneratedSince(&table_start), | |
364 count() * table_entry_size_); | |
365 } | 392 } |
366 | 393 |
367 | 394 |
368 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { | 395 void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) { |
369 SetFrameSlot(offset, value); | 396 SetFrameSlot(offset, value); |
370 } | 397 } |
371 | 398 |
372 | 399 |
373 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { | 400 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) { |
374 SetFrameSlot(offset, value); | 401 SetFrameSlot(offset, value); |
375 } | 402 } |
376 | 403 |
377 | 404 |
378 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { | 405 void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { |
379 // No out-of-line constant pool support. | 406 // No out-of-line constant pool support. |
380 UNREACHABLE(); | 407 UNREACHABLE(); |
381 } | 408 } |
382 | 409 |
383 | 410 |
384 #undef __ | 411 #undef __ |
385 | 412 |
386 | 413 |
387 } } // namespace v8::internal | 414 } } // namespace v8::internal |
OLD | NEW |