Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(155)

Side by Side Diff: src/deoptimizer.cc

Issue 6815010: Merge r7516, r7541 into 3.1 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/3.1/
Patch Set: Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/deoptimizer.h ('k') | src/frames.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 unsigned bailout_id, 189 unsigned bailout_id,
190 Address from, 190 Address from,
191 int fp_to_sp_delta) 191 int fp_to_sp_delta)
192 : function_(function), 192 : function_(function),
193 bailout_id_(bailout_id), 193 bailout_id_(bailout_id),
194 bailout_type_(type), 194 bailout_type_(type),
195 from_(from), 195 from_(from),
196 fp_to_sp_delta_(fp_to_sp_delta), 196 fp_to_sp_delta_(fp_to_sp_delta),
197 output_count_(0), 197 output_count_(0),
198 output_(NULL), 198 output_(NULL),
199 integer32_values_(NULL), 199 deferred_heap_numbers_(0) {
200 double_values_(NULL) {
201 if (FLAG_trace_deopt && type != OSR) { 200 if (FLAG_trace_deopt && type != OSR) {
202 PrintF("**** DEOPT: "); 201 PrintF("**** DEOPT: ");
203 function->PrintName(); 202 function->PrintName();
204 PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n", 203 PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
205 bailout_id, 204 bailout_id,
206 reinterpret_cast<intptr_t>(from), 205 reinterpret_cast<intptr_t>(from),
207 fp_to_sp_delta - (2 * kPointerSize)); 206 fp_to_sp_delta - (2 * kPointerSize));
208 } else if (FLAG_trace_osr && type == OSR) { 207 } else if (FLAG_trace_osr && type == OSR) {
209 PrintF("**** OSR: "); 208 PrintF("**** OSR: ");
210 function->PrintName(); 209 function->PrintName();
(...skipping 18 matching lines...) Expand all
229 ASSERT(!optimized_code_->contains(from)); 228 ASSERT(!optimized_code_->contains(from));
230 } 229 }
231 ASSERT(Heap::allow_allocation(false)); 230 ASSERT(Heap::allow_allocation(false));
232 unsigned size = ComputeInputFrameSize(); 231 unsigned size = ComputeInputFrameSize();
233 input_ = new(size) FrameDescription(size, function); 232 input_ = new(size) FrameDescription(size, function);
234 } 233 }
235 234
236 235
237 Deoptimizer::~Deoptimizer() { 236 Deoptimizer::~Deoptimizer() {
238 ASSERT(input_ == NULL && output_ == NULL); 237 ASSERT(input_ == NULL && output_ == NULL);
239 delete[] integer32_values_;
240 delete[] double_values_;
241 } 238 }
242 239
243 240
244 void Deoptimizer::DeleteFrameDescriptions() { 241 void Deoptimizer::DeleteFrameDescriptions() {
245 delete input_; 242 delete input_;
246 for (int i = 0; i < output_count_; ++i) { 243 for (int i = 0; i < output_count_; ++i) {
247 if (output_[i] != input_) delete output_[i]; 244 if (output_[i] != input_) delete output_[i];
248 } 245 }
249 delete[] output_; 246 delete[] output_;
250 input_ = NULL; 247 input_ = NULL;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 TranslationIterator iterator(translations, translation_index); 372 TranslationIterator iterator(translations, translation_index);
376 Translation::Opcode opcode = 373 Translation::Opcode opcode =
377 static_cast<Translation::Opcode>(iterator.Next()); 374 static_cast<Translation::Opcode>(iterator.Next());
378 ASSERT(Translation::BEGIN == opcode); 375 ASSERT(Translation::BEGIN == opcode);
379 USE(opcode); 376 USE(opcode);
380 // Read the number of output frames and allocate an array for their 377 // Read the number of output frames and allocate an array for their
381 // descriptions. 378 // descriptions.
382 int count = iterator.Next(); 379 int count = iterator.Next();
383 ASSERT(output_ == NULL); 380 ASSERT(output_ == NULL);
384 output_ = new FrameDescription*[count]; 381 output_ = new FrameDescription*[count];
385 // Per-frame lists of untagged and unboxed int32 and double values.
386 integer32_values_ = new List<ValueDescriptionInteger32>[count];
387 double_values_ = new List<ValueDescriptionDouble>[count];
388 for (int i = 0; i < count; ++i) { 382 for (int i = 0; i < count; ++i) {
389 output_[i] = NULL; 383 output_[i] = NULL;
390 integer32_values_[i].Initialize(0);
391 double_values_[i].Initialize(0);
392 } 384 }
393 output_count_ = count; 385 output_count_ = count;
394 386
395 // Translate each output frame. 387 // Translate each output frame.
396 for (int i = 0; i < count; ++i) { 388 for (int i = 0; i < count; ++i) {
397 DoComputeFrame(&iterator, i); 389 DoComputeFrame(&iterator, i);
398 } 390 }
399 391
400 // Print some helpful diagnostic information. 392 // Print some helpful diagnostic information.
401 if (FLAG_trace_deopt) { 393 if (FLAG_trace_deopt) {
402 double ms = static_cast<double>(OS::Ticks() - start) / 1000; 394 double ms = static_cast<double>(OS::Ticks() - start) / 1000;
403 int index = output_count_ - 1; // Index of the topmost frame. 395 int index = output_count_ - 1; // Index of the topmost frame.
404 JSFunction* function = output_[index]->GetFunction(); 396 JSFunction* function = output_[index]->GetFunction();
405 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ", 397 PrintF("[deoptimizing: end 0x%08" V8PRIxPTR " ",
406 reinterpret_cast<intptr_t>(function)); 398 reinterpret_cast<intptr_t>(function));
407 function->PrintName(); 399 function->PrintName();
408 PrintF(" => node=%u, pc=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n", 400 PrintF(" => node=%u, pc=0x%08" V8PRIxPTR ", state=%s, took %0.3f ms]\n",
409 node_id, 401 node_id,
410 output_[index]->GetPc(), 402 output_[index]->GetPc(),
411 FullCodeGenerator::State2String( 403 FullCodeGenerator::State2String(
412 static_cast<FullCodeGenerator::State>( 404 static_cast<FullCodeGenerator::State>(
413 output_[index]->GetState()->value())), 405 output_[index]->GetState()->value())),
414 ms); 406 ms);
415 } 407 }
416 } 408 }
417 409
418 410
419 void Deoptimizer::InsertHeapNumberValues(int index, JavaScriptFrame* frame) { 411 void Deoptimizer::MaterializeHeapNumbers() {
420 // We need to adjust the stack index by one for the top-most frame. 412 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
421 int extra_slot_count = (index == output_count() - 1) ? 1 : 0; 413 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
422 List<ValueDescriptionInteger32>* ints = &integer32_values_[index]; 414 Handle<Object> num = Factory::NewNumber(d.value());
423 for (int i = 0; i < ints->length(); i++) { 415 if (FLAG_trace_deopt) {
424 ValueDescriptionInteger32 value = ints->at(i); 416 PrintF("Materializing a new heap number %p [%e] in slot %p\n",
425 double val = static_cast<double>(value.int32_value()); 417 reinterpret_cast<void*>(*num),
426 InsertHeapNumberValue(frame, value.stack_index(), val, extra_slot_count); 418 d.value(),
419 d.slot_address());
420 }
421
422 Memory::Object_at(d.slot_address()) = *num;
427 } 423 }
428
429 // Iterate over double values and convert them to a heap number.
430 List<ValueDescriptionDouble>* doubles = &double_values_[index];
431 for (int i = 0; i < doubles->length(); ++i) {
432 ValueDescriptionDouble value = doubles->at(i);
433 InsertHeapNumberValue(frame, value.stack_index(), value.double_value(),
434 extra_slot_count);
435 }
436 }
437
438
439 void Deoptimizer::InsertHeapNumberValue(JavaScriptFrame* frame,
440 int stack_index,
441 double val,
442 int extra_slot_count) {
443 // Add one to the TOS index to take the 'state' pushed before jumping
444 // to the stub that calls Runtime::NotifyDeoptimized into account.
445 int tos_index = stack_index + extra_slot_count;
446 int index = (frame->ComputeExpressionsCount() - 1) - tos_index;
447 if (FLAG_trace_deopt) PrintF("Allocating a new heap number: %e\n", val);
448 Handle<Object> num = Factory::NewNumber(val);
449 frame->SetExpression(index, *num);
450 } 424 }
451 425
452 426
453 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 427 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
454 int frame_index, 428 int frame_index,
455 unsigned output_offset) { 429 unsigned output_offset) {
456 disasm::NameConverter converter; 430 disasm::NameConverter converter;
457 // A GC-safe temporary placeholder that we can put in the output frame. 431 // A GC-safe temporary placeholder that we can put in the output frame.
458 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 432 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
459 433
(...skipping 25 matching lines...) Expand all
485 converter.NameOfCPURegister(input_reg)); 459 converter.NameOfCPURegister(input_reg));
486 } 460 }
487 output_[frame_index]->SetFrameSlot(output_offset, input_value); 461 output_[frame_index]->SetFrameSlot(output_offset, input_value);
488 return; 462 return;
489 } 463 }
490 464
491 case Translation::INT32_REGISTER: { 465 case Translation::INT32_REGISTER: {
492 int input_reg = iterator->Next(); 466 int input_reg = iterator->Next();
493 intptr_t value = input_->GetRegister(input_reg); 467 intptr_t value = input_->GetRegister(input_reg);
494 bool is_smi = Smi::IsValid(value); 468 bool is_smi = Smi::IsValid(value);
495 unsigned output_index = output_offset / kPointerSize;
496 if (FLAG_trace_deopt) { 469 if (FLAG_trace_deopt) {
497 PrintF( 470 PrintF(
498 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n", 471 " 0x%08" V8PRIxPTR ": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
499 output_[frame_index]->GetTop() + output_offset, 472 output_[frame_index]->GetTop() + output_offset,
500 output_offset, 473 output_offset,
501 value, 474 value,
502 converter.NameOfCPURegister(input_reg), 475 converter.NameOfCPURegister(input_reg),
503 is_smi ? "smi" : "heap number"); 476 is_smi ? "smi" : "heap number");
504 } 477 }
505 if (is_smi) { 478 if (is_smi) {
506 intptr_t tagged_value = 479 intptr_t tagged_value =
507 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 480 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
508 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 481 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
509 } else { 482 } else {
510 // We save the untagged value on the side and store a GC-safe 483 // We save the untagged value on the side and store a GC-safe
511 // temporary placeholder in the frame. 484 // temporary placeholder in the frame.
512 AddInteger32Value(frame_index, 485 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
513 output_index, 486 static_cast<double>(static_cast<int32_t>(value)));
514 static_cast<int32_t>(value));
515 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 487 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
516 } 488 }
517 return; 489 return;
518 } 490 }
519 491
520 case Translation::DOUBLE_REGISTER: { 492 case Translation::DOUBLE_REGISTER: {
521 int input_reg = iterator->Next(); 493 int input_reg = iterator->Next();
522 double value = input_->GetDoubleRegister(input_reg); 494 double value = input_->GetDoubleRegister(input_reg);
523 unsigned output_index = output_offset / kPointerSize;
524 if (FLAG_trace_deopt) { 495 if (FLAG_trace_deopt) {
525 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n", 496 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
526 output_[frame_index]->GetTop() + output_offset, 497 output_[frame_index]->GetTop() + output_offset,
527 output_offset, 498 output_offset,
528 value, 499 value,
529 DoubleRegister::AllocationIndexToString(input_reg)); 500 DoubleRegister::AllocationIndexToString(input_reg));
530 } 501 }
531 // We save the untagged value on the side and store a GC-safe 502 // We save the untagged value on the side and store a GC-safe
532 // temporary placeholder in the frame. 503 // temporary placeholder in the frame.
533 AddDoubleValue(frame_index, output_index, value); 504 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
534 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 505 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
535 return; 506 return;
536 } 507 }
537 508
538 case Translation::STACK_SLOT: { 509 case Translation::STACK_SLOT: {
539 int input_slot_index = iterator->Next(); 510 int input_slot_index = iterator->Next();
540 unsigned input_offset = 511 unsigned input_offset =
541 input_->GetOffsetFromSlotIndex(this, input_slot_index); 512 input_->GetOffsetFromSlotIndex(this, input_slot_index);
542 intptr_t input_value = input_->GetFrameSlot(input_offset); 513 intptr_t input_value = input_->GetFrameSlot(input_offset);
543 if (FLAG_trace_deopt) { 514 if (FLAG_trace_deopt) {
544 PrintF(" 0x%08" V8PRIxPTR ": ", 515 PrintF(" 0x%08" V8PRIxPTR ": ",
545 output_[frame_index]->GetTop() + output_offset); 516 output_[frame_index]->GetTop() + output_offset);
546 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d]\n", 517 PrintF("[top + %d] <- 0x%08" V8PRIxPTR " ; [esp + %d]\n",
547 output_offset, 518 output_offset,
548 input_value, 519 input_value,
549 input_offset); 520 input_offset);
550 } 521 }
551 output_[frame_index]->SetFrameSlot(output_offset, input_value); 522 output_[frame_index]->SetFrameSlot(output_offset, input_value);
552 return; 523 return;
553 } 524 }
554 525
555 case Translation::INT32_STACK_SLOT: { 526 case Translation::INT32_STACK_SLOT: {
556 int input_slot_index = iterator->Next(); 527 int input_slot_index = iterator->Next();
557 unsigned input_offset = 528 unsigned input_offset =
558 input_->GetOffsetFromSlotIndex(this, input_slot_index); 529 input_->GetOffsetFromSlotIndex(this, input_slot_index);
559 intptr_t value = input_->GetFrameSlot(input_offset); 530 intptr_t value = input_->GetFrameSlot(input_offset);
560 bool is_smi = Smi::IsValid(value); 531 bool is_smi = Smi::IsValid(value);
561 unsigned output_index = output_offset / kPointerSize;
562 if (FLAG_trace_deopt) { 532 if (FLAG_trace_deopt) {
563 PrintF(" 0x%08" V8PRIxPTR ": ", 533 PrintF(" 0x%08" V8PRIxPTR ": ",
564 output_[frame_index]->GetTop() + output_offset); 534 output_[frame_index]->GetTop() + output_offset);
565 PrintF("[top + %d] <- %" V8PRIdPTR " ; [esp + %d] (%s)\n", 535 PrintF("[top + %d] <- %" V8PRIdPTR " ; [esp + %d] (%s)\n",
566 output_offset, 536 output_offset,
567 value, 537 value,
568 input_offset, 538 input_offset,
569 is_smi ? "smi" : "heap number"); 539 is_smi ? "smi" : "heap number");
570 } 540 }
571 if (is_smi) { 541 if (is_smi) {
572 intptr_t tagged_value = 542 intptr_t tagged_value =
573 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value))); 543 reinterpret_cast<intptr_t>(Smi::FromInt(static_cast<int>(value)));
574 output_[frame_index]->SetFrameSlot(output_offset, tagged_value); 544 output_[frame_index]->SetFrameSlot(output_offset, tagged_value);
575 } else { 545 } else {
576 // We save the untagged value on the side and store a GC-safe 546 // We save the untagged value on the side and store a GC-safe
577 // temporary placeholder in the frame. 547 // temporary placeholder in the frame.
578 AddInteger32Value(frame_index, 548 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
579 output_index, 549 static_cast<double>(static_cast<int32_t>(value)));
580 static_cast<int32_t>(value));
581 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 550 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
582 } 551 }
583 return; 552 return;
584 } 553 }
585 554
586 case Translation::DOUBLE_STACK_SLOT: { 555 case Translation::DOUBLE_STACK_SLOT: {
587 int input_slot_index = iterator->Next(); 556 int input_slot_index = iterator->Next();
588 unsigned input_offset = 557 unsigned input_offset =
589 input_->GetOffsetFromSlotIndex(this, input_slot_index); 558 input_->GetOffsetFromSlotIndex(this, input_slot_index);
590 double value = input_->GetDoubleFrameSlot(input_offset); 559 double value = input_->GetDoubleFrameSlot(input_offset);
591 unsigned output_index = output_offset / kPointerSize;
592 if (FLAG_trace_deopt) { 560 if (FLAG_trace_deopt) {
593 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [esp + %d]\n", 561 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [esp + %d]\n",
594 output_[frame_index]->GetTop() + output_offset, 562 output_[frame_index]->GetTop() + output_offset,
595 output_offset, 563 output_offset,
596 value, 564 value,
597 input_offset); 565 input_offset);
598 } 566 }
599 // We save the untagged value on the side and store a GC-safe 567 // We save the untagged value on the side and store a GC-safe
600 // temporary placeholder in the frame. 568 // temporary placeholder in the frame.
601 AddDoubleValue(frame_index, output_index, value); 569 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
602 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder); 570 output_[frame_index]->SetFrameSlot(output_offset, kPlaceholder);
603 return; 571 return;
604 } 572 }
605 573
606 case Translation::LITERAL: { 574 case Translation::LITERAL: {
607 Object* literal = ComputeLiteral(iterator->Next()); 575 Object* literal = ComputeLiteral(iterator->Next());
608 if (FLAG_trace_deopt) { 576 if (FLAG_trace_deopt) {
609 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ", 577 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- ",
610 output_[frame_index]->GetTop() + output_offset, 578 output_[frame_index]->GetTop() + output_offset,
611 output_offset); 579 output_offset);
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 862
895 863
896 Object* Deoptimizer::ComputeLiteral(int index) const { 864 Object* Deoptimizer::ComputeLiteral(int index) const {
897 DeoptimizationInputData* data = DeoptimizationInputData::cast( 865 DeoptimizationInputData* data = DeoptimizationInputData::cast(
898 optimized_code_->deoptimization_data()); 866 optimized_code_->deoptimization_data());
899 FixedArray* literals = data->LiteralArray(); 867 FixedArray* literals = data->LiteralArray();
900 return literals->get(index); 868 return literals->get(index);
901 } 869 }
902 870
903 871
904 void Deoptimizer::AddInteger32Value(int frame_index, 872 void Deoptimizer::AddDoubleValue(intptr_t slot_address,
905 int slot_index, 873 double value) {
906 int32_t value) { 874 HeapNumberMaterializationDescriptor value_desc(
907 ValueDescriptionInteger32 value_desc(slot_index, value); 875 reinterpret_cast<Address>(slot_address), value);
908 integer32_values_[frame_index].Add(value_desc); 876 deferred_heap_numbers_.Add(value_desc);
909 } 877 }
910 878
911 879
912 void Deoptimizer::AddDoubleValue(int frame_index,
913 int slot_index,
914 double value) {
915 ValueDescriptionDouble value_desc(slot_index, value);
916 double_values_[frame_index].Add(value_desc);
917 }
918
919
920 LargeObjectChunk* Deoptimizer::CreateCode(BailoutType type) { 880 LargeObjectChunk* Deoptimizer::CreateCode(BailoutType type) {
921 // We cannot run this if the serializer is enabled because this will 881 // We cannot run this if the serializer is enabled because this will
922 // cause us to emit relocation information for the external 882 // cause us to emit relocation information for the external
923 // references. This is fine because the deoptimizer's code section 883 // references. This is fine because the deoptimizer's code section
924 // isn't meant to be serialized at all. 884 // isn't meant to be serialized at all.
925 ASSERT(!Serializer::enabled()); 885 ASSERT(!Serializer::enabled());
926 bool old_debug_code = FLAG_debug_code; 886 bool old_debug_code = FLAG_debug_code;
927 FLAG_debug_code = false; 887 FLAG_debug_code = false;
928 888
929 MacroAssembler masm(NULL, 16 * KB); 889 MacroAssembler masm(NULL, 16 * KB);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 Deoptimizer::HandleWeakDeoptimizedCode); 1136 Deoptimizer::HandleWeakDeoptimizedCode);
1177 } 1137 }
1178 1138
1179 1139
1180 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() { 1140 DeoptimizingCodeListNode::~DeoptimizingCodeListNode() {
1181 GlobalHandles::Destroy(reinterpret_cast<Object**>(code_.location())); 1141 GlobalHandles::Destroy(reinterpret_cast<Object**>(code_.location()));
1182 } 1142 }
1183 1143
1184 1144
1185 } } // namespace v8::internal 1145 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/frames.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698