~ubuntu-branches/ubuntu/saucy/libv8/saucy

« back to all changes in this revision

Viewing changes to src/x64/deoptimizer-x64.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2012-04-07 16:26:13 UTC
  • mfrom: (15.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120407162613-dqo1m6w9r3fh8tst
Tags: 3.8.9.16-3
* mipsel build fixes :
  + v8_use_mips_abi_hardfloat=false, this lowers EABI requirements.
  + v8_can_use_fpu_instructions=false, detect if FPU is present.
  + set -Wno-unused-but-set-variable only on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
138
138
  ASSERT(*(call_target_address - 3) == 0x73 &&  // jae
139
139
         *(call_target_address - 2) == 0x07 &&  // offset
140
140
         *(call_target_address - 1) == 0xe8);   // call
141
 
  *(call_target_address - 3) = 0x90;  // nop
142
 
  *(call_target_address - 2) = 0x90;  // nop
 
141
  *(call_target_address - 3) = 0x66;  // 2 byte nop part 1
 
142
  *(call_target_address - 2) = 0x90;  // 2 byte nop part 2
143
143
  Assembler::set_target_address_at(call_target_address,
144
144
                                   replacement_code->entry());
145
145
 
157
157
         Assembler::target_address_at(call_target_address));
158
158
  // Replace the nops from patching (Deoptimizer::PatchStackCheckCode) to
159
159
  // restore the conditional branch.
160
 
  ASSERT(*(call_target_address - 3) == 0x90 &&  // nop
161
 
         *(call_target_address - 2) == 0x90 &&  // nop
 
160
  ASSERT(*(call_target_address - 3) == 0x66 &&  // 2 byte nop part 1
 
161
         *(call_target_address - 2) == 0x90 &&  // 2 byte nop part 2
162
162
         *(call_target_address - 1) == 0xe8);   // call
163
163
  *(call_target_address - 3) = 0x73;  // jae
164
164
  *(call_target_address - 2) = 0x07;  // offset
206
206
  ASSERT(Translation::BEGIN == opcode);
207
207
  USE(opcode);
208
208
  int count = iterator.Next();
 
209
  iterator.Skip(1);  // Drop JS frame count.
209
210
  ASSERT(count == 1);
210
211
  USE(count);
211
212
 
212
213
  opcode = static_cast<Translation::Opcode>(iterator.Next());
213
214
  USE(opcode);
214
 
  ASSERT(Translation::FRAME == opcode);
 
215
  ASSERT(Translation::JS_FRAME == opcode);
215
216
  unsigned node_id = iterator.Next();
216
217
  USE(node_id);
217
218
  ASSERT(node_id == ast_id);
247
248
  output_ = new FrameDescription*[1];
248
249
  output_[0] = new(output_frame_size) FrameDescription(
249
250
      output_frame_size, function_);
250
 
#ifdef DEBUG
251
 
  output_[0]->SetKind(Code::OPTIMIZED_FUNCTION);
252
 
#endif
 
251
  output_[0]->SetFrameType(StackFrame::JAVA_SCRIPT);
253
252
 
254
253
  // Clear the incoming parameters in the optimized frame to avoid
255
254
  // confusing the garbage collector.
314
313
    output_[0] = input_;
315
314
    output_[0]->SetPc(reinterpret_cast<intptr_t>(from_));
316
315
  } else {
317
 
    // Setup the frame pointer and the context pointer.
 
316
    // Set up the frame pointer and the context pointer.
318
317
    output_[0]->SetRegister(rbp.code(), input_->GetRegister(rbp.code()));
319
318
    output_[0]->SetRegister(rsi.code(), input_->GetRegister(rsi.code()));
320
319
 
338
337
}
339
338
 
340
339
 
341
 
void Deoptimizer::DoComputeFrame(TranslationIterator* iterator,
342
 
                                 int frame_index) {
343
 
  // Read the ast node id, function, and frame height for this output frame.
344
 
  Translation::Opcode opcode =
345
 
      static_cast<Translation::Opcode>(iterator->Next());
346
 
  USE(opcode);
347
 
  ASSERT(Translation::FRAME == opcode);
 
340
void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
 
341
                                                 int frame_index) {
 
342
  JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
 
343
  unsigned height = iterator->Next();
 
344
  unsigned height_in_bytes = height * kPointerSize;
 
345
  if (FLAG_trace_deopt) {
 
346
    PrintF("  translating arguments adaptor => height=%d\n", height_in_bytes);
 
347
  }
 
348
 
 
349
  unsigned fixed_frame_size = ArgumentsAdaptorFrameConstants::kFrameSize;
 
350
  unsigned input_frame_size = input_->GetFrameSize();
 
351
  unsigned output_frame_size = height_in_bytes + fixed_frame_size;
 
352
 
 
353
  // Allocate and store the output frame description.
 
354
  FrameDescription* output_frame =
 
355
      new(output_frame_size) FrameDescription(output_frame_size, function);
 
356
  output_frame->SetFrameType(StackFrame::ARGUMENTS_ADAPTOR);
 
357
 
 
358
  // Arguments adaptor can not be topmost or bottommost.
 
359
  ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
 
360
  ASSERT(output_[frame_index] == NULL);
 
361
  output_[frame_index] = output_frame;
 
362
 
 
363
  // The top address of the frame is computed from the previous
 
364
  // frame's top and this frame's size.
 
365
  intptr_t top_address;
 
366
  top_address = output_[frame_index - 1]->GetTop() - output_frame_size;
 
367
  output_frame->SetTop(top_address);
 
368
 
 
369
  // Compute the incoming parameter translation.
 
370
  int parameter_count = height;
 
371
  unsigned output_offset = output_frame_size;
 
372
  unsigned input_offset = input_frame_size;
 
373
  for (int i = 0; i < parameter_count; ++i) {
 
374
    output_offset -= kPointerSize;
 
375
    DoTranslateCommand(iterator, frame_index, output_offset);
 
376
  }
 
377
  input_offset -= (parameter_count * kPointerSize);
 
378
 
 
379
  // Read caller's PC from the previous frame.
 
380
  output_offset -= kPointerSize;
 
381
  input_offset -= kPointerSize;
 
382
  intptr_t callers_pc = output_[frame_index - 1]->GetPc();
 
383
  output_frame->SetFrameSlot(output_offset, callers_pc);
 
384
  if (FLAG_trace_deopt) {
 
385
    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
 
386
           V8PRIxPTR " ; caller's pc\n",
 
387
           top_address + output_offset, output_offset, callers_pc);
 
388
  }
 
389
 
 
390
  // Read caller's FP from the previous frame, and set this frame's FP.
 
391
  output_offset -= kPointerSize;
 
392
  input_offset -= kPointerSize;
 
393
  intptr_t value = output_[frame_index - 1]->GetFp();
 
394
  output_frame->SetFrameSlot(output_offset, value);
 
395
  intptr_t fp_value = top_address + output_offset;
 
396
  output_frame->SetFp(fp_value);
 
397
  if (FLAG_trace_deopt) {
 
398
    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
 
399
           V8PRIxPTR " ; caller's fp\n",
 
400
           fp_value, output_offset, value);
 
401
  }
 
402
 
 
403
  // A marker value is used in place of the context.
 
404
  output_offset -= kPointerSize;
 
405
  input_offset -= kPointerSize;
 
406
  intptr_t context = reinterpret_cast<intptr_t>(
 
407
      Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
 
408
  output_frame->SetFrameSlot(output_offset, context);
 
409
  if (FLAG_trace_deopt) {
 
410
    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
 
411
           V8PRIxPTR " ; context (adaptor sentinel)\n",
 
412
           top_address + output_offset, output_offset, context);
 
413
  }
 
414
 
 
415
  // The function was mentioned explicitly in the ARGUMENTS_ADAPTOR_FRAME.
 
416
  output_offset -= kPointerSize;
 
417
  input_offset -= kPointerSize;
 
418
  value = reinterpret_cast<intptr_t>(function);
 
419
  output_frame->SetFrameSlot(output_offset, value);
 
420
  if (FLAG_trace_deopt) {
 
421
    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
 
422
           V8PRIxPTR " ; function\n",
 
423
           top_address + output_offset, output_offset, value);
 
424
  }
 
425
 
 
426
  // Number of incoming arguments.
 
427
  output_offset -= kPointerSize;
 
428
  input_offset -= kPointerSize;
 
429
  value = reinterpret_cast<intptr_t>(Smi::FromInt(height - 1));
 
430
  output_frame->SetFrameSlot(output_offset, value);
 
431
  if (FLAG_trace_deopt) {
 
432
    PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
 
433
           V8PRIxPTR " ; argc (%d)\n",
 
434
           top_address + output_offset, output_offset, value, height - 1);
 
435
  }
 
436
 
 
437
  ASSERT(0 == output_offset);
 
438
 
 
439
  Builtins* builtins = isolate_->builtins();
 
440
  Code* adaptor_trampoline =
 
441
      builtins->builtin(Builtins::kArgumentsAdaptorTrampoline);
 
442
  intptr_t pc_value = reinterpret_cast<intptr_t>(
 
443
      adaptor_trampoline->instruction_start() +
 
444
      isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
 
445
  output_frame->SetPc(pc_value);
 
446
}
 
447
 
 
448
 
 
449
void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
 
450
                                   int frame_index) {
348
451
  int node_id = iterator->Next();
349
452
  JSFunction* function = JSFunction::cast(ComputeLiteral(iterator->Next()));
350
453
  unsigned height = iterator->Next();
364
467
  // Allocate and store the output frame description.
365
468
  FrameDescription* output_frame =
366
469
      new(output_frame_size) FrameDescription(output_frame_size, function);
367
 
#ifdef DEBUG
368
 
  output_frame->SetKind(Code::FUNCTION);
369
 
#endif
 
470
  output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
370
471
 
371
472
  bool is_bottommost = (0 == frame_index);
372
473
  bool is_topmost = (output_count_ - 1 == frame_index);