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

Side by Side Diff: src/mark-compact.cc

Issue 8888011: Ensure that non-optimized code objects are not flushed for inlined functions. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years 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/mark-compact.h ('k') | src/objects.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 601 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 : isolate_(isolate), 612 : isolate_(isolate),
613 jsfunction_candidates_head_(NULL), 613 jsfunction_candidates_head_(NULL),
614 shared_function_info_candidates_head_(NULL) {} 614 shared_function_info_candidates_head_(NULL) {}
615 615
616 void AddCandidate(SharedFunctionInfo* shared_info) { 616 void AddCandidate(SharedFunctionInfo* shared_info) {
617 SetNextCandidate(shared_info, shared_function_info_candidates_head_); 617 SetNextCandidate(shared_info, shared_function_info_candidates_head_);
618 shared_function_info_candidates_head_ = shared_info; 618 shared_function_info_candidates_head_ = shared_info;
619 } 619 }
620 620
621 void AddCandidate(JSFunction* function) { 621 void AddCandidate(JSFunction* function) {
622 ASSERT(function->unchecked_code() == 622 ASSERT(function->code() == function->shared()->code());
623 function->unchecked_shared()->unchecked_code());
624 623
625 SetNextCandidate(function, jsfunction_candidates_head_); 624 SetNextCandidate(function, jsfunction_candidates_head_);
626 jsfunction_candidates_head_ = function; 625 jsfunction_candidates_head_ = function;
627 } 626 }
628 627
629 void ProcessCandidates() { 628 void ProcessCandidates() {
630 ProcessSharedFunctionInfoCandidates(); 629 ProcessSharedFunctionInfoCandidates();
631 ProcessJSFunctionCandidates(); 630 ProcessJSFunctionCandidates();
632 } 631 }
633 632
634 private: 633 private:
635 void ProcessJSFunctionCandidates() { 634 void ProcessJSFunctionCandidates() {
636 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); 635 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
637 636
638 JSFunction* candidate = jsfunction_candidates_head_; 637 JSFunction* candidate = jsfunction_candidates_head_;
639 JSFunction* next_candidate; 638 JSFunction* next_candidate;
640 while (candidate != NULL) { 639 while (candidate != NULL) {
641 next_candidate = GetNextCandidate(candidate); 640 next_candidate = GetNextCandidate(candidate);
642 641
643 SharedFunctionInfo* shared = candidate->unchecked_shared(); 642 SharedFunctionInfo* shared = candidate->shared();
644 643
645 Code* code = shared->unchecked_code(); 644 Code* code = shared->code();
646 MarkBit code_mark = Marking::MarkBitFrom(code); 645 MarkBit code_mark = Marking::MarkBitFrom(code);
647 if (!code_mark.Get()) { 646 if (!code_mark.Get()) {
648 shared->set_code(lazy_compile); 647 shared->set_code(lazy_compile);
649 candidate->set_code(lazy_compile); 648 candidate->set_code(lazy_compile);
650 } else { 649 } else {
651 candidate->set_code(shared->unchecked_code()); 650 candidate->set_code(shared->code());
652 } 651 }
653 652
654 // We are in the middle of a GC cycle so the write barrier in the code 653 // We are in the middle of a GC cycle so the write barrier in the code
655 // setter did not record the slot update and we have to do that manually. 654 // setter did not record the slot update and we have to do that manually.
656 Address slot = candidate->address() + JSFunction::kCodeEntryOffset; 655 Address slot = candidate->address() + JSFunction::kCodeEntryOffset;
657 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot)); 656 Code* target = Code::cast(Code::GetObjectFromEntryAddress(slot));
658 isolate_->heap()->mark_compact_collector()-> 657 isolate_->heap()->mark_compact_collector()->
659 RecordCodeEntrySlot(slot, target); 658 RecordCodeEntrySlot(slot, target);
660 659
661 candidate = next_candidate; 660 candidate = next_candidate;
662 } 661 }
663 662
664 jsfunction_candidates_head_ = NULL; 663 jsfunction_candidates_head_ = NULL;
665 } 664 }
666 665
667 666
668 void ProcessSharedFunctionInfoCandidates() { 667 void ProcessSharedFunctionInfoCandidates() {
669 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile); 668 Code* lazy_compile = isolate_->builtins()->builtin(Builtins::kLazyCompile);
670 669
671 SharedFunctionInfo* candidate = shared_function_info_candidates_head_; 670 SharedFunctionInfo* candidate = shared_function_info_candidates_head_;
672 SharedFunctionInfo* next_candidate; 671 SharedFunctionInfo* next_candidate;
673 while (candidate != NULL) { 672 while (candidate != NULL) {
674 next_candidate = GetNextCandidate(candidate); 673 next_candidate = GetNextCandidate(candidate);
675 SetNextCandidate(candidate, NULL); 674 SetNextCandidate(candidate, NULL);
676 675
677 Code* code = candidate->unchecked_code(); 676 Code* code = candidate->code();
678 MarkBit code_mark = Marking::MarkBitFrom(code); 677 MarkBit code_mark = Marking::MarkBitFrom(code);
679 if (!code_mark.Get()) { 678 if (!code_mark.Get()) {
680 candidate->set_code(lazy_compile); 679 candidate->set_code(lazy_compile);
681 } 680 }
682 681
683 candidate = next_candidate; 682 candidate = next_candidate;
684 } 683 }
685 684
686 shared_function_info_candidates_head_ = NULL; 685 shared_function_info_candidates_head_ = NULL;
687 } 686 }
688 687
689 static JSFunction** GetNextCandidateField(JSFunction* candidate) { 688 static JSFunction** GetNextCandidateField(JSFunction* candidate) {
690 return reinterpret_cast<JSFunction**>( 689 return reinterpret_cast<JSFunction**>(
691 candidate->address() + JSFunction::kCodeEntryOffset); 690 candidate->address() + JSFunction::kCodeEntryOffset);
692 } 691 }
693 692
694 static JSFunction* GetNextCandidate(JSFunction* candidate) { 693 static JSFunction* GetNextCandidate(JSFunction* candidate) {
695 return *GetNextCandidateField(candidate); 694 return *GetNextCandidateField(candidate);
696 } 695 }
697 696
698 static void SetNextCandidate(JSFunction* candidate, 697 static void SetNextCandidate(JSFunction* candidate,
699 JSFunction* next_candidate) { 698 JSFunction* next_candidate) {
700 *GetNextCandidateField(candidate) = next_candidate; 699 *GetNextCandidateField(candidate) = next_candidate;
701 } 700 }
702 701
703 static SharedFunctionInfo** GetNextCandidateField( 702 static SharedFunctionInfo** GetNextCandidateField(
704 SharedFunctionInfo* candidate) { 703 SharedFunctionInfo* candidate) {
705 Code* code = candidate->unchecked_code(); 704 Code* code = candidate->code();
706 return reinterpret_cast<SharedFunctionInfo**>( 705 return reinterpret_cast<SharedFunctionInfo**>(
707 code->address() + Code::kNextCodeFlushingCandidateOffset); 706 code->address() + Code::kNextCodeFlushingCandidateOffset);
708 } 707 }
709 708
710 static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) { 709 static SharedFunctionInfo* GetNextCandidate(SharedFunctionInfo* candidate) {
711 return *GetNextCandidateField(candidate); 710 return *GetNextCandidateField(candidate);
712 } 711 }
713 712
714 static void SetNextCandidate(SharedFunctionInfo* candidate, 713 static void SetNextCandidate(SharedFunctionInfo* candidate,
715 SharedFunctionInfo* next_candidate) { 714 SharedFunctionInfo* next_candidate) {
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 static const int kRegExpCodeThreshold = 5; 1029 static const int kRegExpCodeThreshold = 5;
1031 1030
1032 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) { 1031 inline static bool HasSourceCode(Heap* heap, SharedFunctionInfo* info) {
1033 Object* undefined = heap->undefined_value(); 1032 Object* undefined = heap->undefined_value();
1034 return (info->script() != undefined) && 1033 return (info->script() != undefined) &&
1035 (reinterpret_cast<Script*>(info->script())->source() != undefined); 1034 (reinterpret_cast<Script*>(info->script())->source() != undefined);
1036 } 1035 }
1037 1036
1038 1037
1039 inline static bool IsCompiled(JSFunction* function) { 1038 inline static bool IsCompiled(JSFunction* function) {
1040 return function->unchecked_code() != 1039 return function->code() !=
1041 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 1040 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
1042 } 1041 }
1043 1042
1044 inline static bool IsCompiled(SharedFunctionInfo* function) { 1043 inline static bool IsCompiled(SharedFunctionInfo* function) {
1045 return function->unchecked_code() != 1044 return function->code() !=
1046 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile); 1045 function->GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
1047 } 1046 }
1048 1047
1049 inline static bool IsFlushable(Heap* heap, JSFunction* function) { 1048 inline static bool IsFlushable(Heap* heap, JSFunction* function) {
1050 SharedFunctionInfo* shared_info = function->unchecked_shared(); 1049 SharedFunctionInfo* shared_info = function->unchecked_shared();
1051 1050
1052 // Code is either on stack, in compilation cache or referenced 1051 // Code is either on stack, in compilation cache or referenced
1053 // by optimized version of function. 1052 // by optimized version of function.
1054 MarkBit code_mark = 1053 MarkBit code_mark = Marking::MarkBitFrom(function->code());
1055 Marking::MarkBitFrom(function->unchecked_code());
1056 if (code_mark.Get()) { 1054 if (code_mark.Get()) {
1057 if (!Marking::MarkBitFrom(shared_info).Get()) { 1055 if (!Marking::MarkBitFrom(shared_info).Get()) {
1058 shared_info->set_code_age(0); 1056 shared_info->set_code_age(0);
1059 } 1057 }
1060 return false; 1058 return false;
1061 } 1059 }
1062 1060
1063 // We do not flush code for optimized functions. 1061 // We do not flush code for optimized functions.
1064 if (function->code() != shared_info->unchecked_code()) { 1062 if (function->code() != shared_info->code()) {
1065 return false; 1063 return false;
1066 } 1064 }
1067 1065
1068 return IsFlushable(heap, shared_info); 1066 return IsFlushable(heap, shared_info);
1069 } 1067 }
1070 1068
1071 inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) { 1069 inline static bool IsFlushable(Heap* heap, SharedFunctionInfo* shared_info) {
1072 // Code is either on stack, in compilation cache or referenced 1070 // Code is either on stack, in compilation cache or referenced
1073 // by optimized version of function. 1071 // by optimized version of function.
1074 MarkBit code_mark = 1072 MarkBit code_mark =
1075 Marking::MarkBitFrom(shared_info->unchecked_code()); 1073 Marking::MarkBitFrom(shared_info->code());
1076 if (code_mark.Get()) { 1074 if (code_mark.Get()) {
1077 return false; 1075 return false;
1078 } 1076 }
1079 1077
1080 // The function must be compiled and have the source code available, 1078 // The function must be compiled and have the source code available,
1081 // to be able to recompile it in case we need the function again. 1079 // to be able to recompile it in case we need the function again.
1082 if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) { 1080 if (!(shared_info->is_compiled() && HasSourceCode(heap, shared_info))) {
1083 return false; 1081 return false;
1084 } 1082 }
1085 1083
1086 // We never flush code for Api functions. 1084 // We never flush code for Api functions.
1087 Object* function_data = shared_info->function_data(); 1085 Object* function_data = shared_info->function_data();
1088 if (function_data->IsFunctionTemplateInfo()) return false; 1086 if (function_data->IsFunctionTemplateInfo()) {
1087 return false;
1088 }
1089 1089
1090 // Only flush code for functions. 1090 // Only flush code for functions.
1091 if (shared_info->code()->kind() != Code::FUNCTION) return false; 1091 if (shared_info->code()->kind() != Code::FUNCTION) {
1092 return false;
1093 }
1092 1094
1093 // Function must be lazy compilable. 1095 // Function must be lazy compilable.
1094 if (!shared_info->allows_lazy_compilation()) return false; 1096 if (!shared_info->allows_lazy_compilation()) {
1097 return false;
1098 }
1095 1099
1096 // If this is a full script wrapped in a function we do no flush the code. 1100 // If this is a full script wrapped in a function we do no flush the code.
1097 if (shared_info->is_toplevel()) return false; 1101 if (shared_info->is_toplevel()) {
1102 return false;
1103 }
1098 1104
1099 // Age this shared function info. 1105 // Age this shared function info.
1100 if (shared_info->code_age() < kCodeAgeThreshold) { 1106 if (shared_info->code_age() < kCodeAgeThreshold) {
1101 shared_info->set_code_age(shared_info->code_age() + 1); 1107 shared_info->set_code_age(shared_info->code_age() + 1);
1102 return false; 1108 return false;
1103 } 1109 }
1104 1110
1105 return true; 1111 return true;
1106 } 1112 }
1107 1113
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 } 1266 }
1261 1267
1262 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); 1268 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object);
1263 // The function must have a valid context and not be a builtin. 1269 // The function must have a valid context and not be a builtin.
1264 bool flush_code_candidate = false; 1270 bool flush_code_candidate = false;
1265 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { 1271 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) {
1266 flush_code_candidate = FlushCodeForFunction(heap, jsfunction); 1272 flush_code_candidate = FlushCodeForFunction(heap, jsfunction);
1267 } 1273 }
1268 1274
1269 if (!flush_code_candidate) { 1275 if (!flush_code_candidate) {
1270 Code* code = jsfunction->unchecked_shared()->unchecked_code(); 1276 Code* code = jsfunction->shared()->code();
1271 MarkBit code_mark = Marking::MarkBitFrom(code); 1277 MarkBit code_mark = Marking::MarkBitFrom(code);
1272 heap->mark_compact_collector()->MarkObject(code, code_mark); 1278 collector->MarkObject(code, code_mark);
1273 1279
1274 if (jsfunction->unchecked_code()->kind() == Code::OPTIMIZED_FUNCTION) { 1280 if (jsfunction->code()->kind() == Code::OPTIMIZED_FUNCTION) {
1275 // For optimized functions we should retain both non-optimized version 1281 collector->MarkInlinedFunctionsCode(jsfunction->code());
1276 // of it's code and non-optimized version of all inlined functions.
1277 // This is required to support bailing out from inlined code.
1278 DeoptimizationInputData* data =
1279 reinterpret_cast<DeoptimizationInputData*>(
1280 jsfunction->unchecked_code()->unchecked_deoptimization_data());
1281
1282 FixedArray* literals = data->UncheckedLiteralArray();
1283
1284 for (int i = 0, count = data->InlinedFunctionCount()->value();
1285 i < count;
1286 i++) {
1287 JSFunction* inlined = reinterpret_cast<JSFunction*>(literals->get(i));
1288 Code* inlined_code = inlined->unchecked_shared()->unchecked_code();
1289 MarkBit inlined_code_mark =
1290 Marking::MarkBitFrom(inlined_code);
1291 heap->mark_compact_collector()->MarkObject(
1292 inlined_code, inlined_code_mark);
1293 }
1294 } 1282 }
1295 } 1283 }
1296 1284
1297 VisitJSFunctionFields(map, 1285 VisitJSFunctionFields(map,
1298 reinterpret_cast<JSFunction*>(object), 1286 reinterpret_cast<JSFunction*>(object),
1299 flush_code_candidate); 1287 flush_code_candidate);
1300 } 1288 }
1301 1289
1302 1290
1303 static void VisitJSFunction(Map* map, HeapObject* object) { 1291 static void VisitJSFunction(Map* map, HeapObject* object) {
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 Heap* heap_; 1396 Heap* heap_;
1409 }; 1397 };
1410 1398
1411 1399
1412 class CodeMarkingVisitor : public ThreadVisitor { 1400 class CodeMarkingVisitor : public ThreadVisitor {
1413 public: 1401 public:
1414 explicit CodeMarkingVisitor(MarkCompactCollector* collector) 1402 explicit CodeMarkingVisitor(MarkCompactCollector* collector)
1415 : collector_(collector) {} 1403 : collector_(collector) {}
1416 1404
1417 void VisitThread(Isolate* isolate, ThreadLocalTop* top) { 1405 void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
1418 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) { 1406 collector_->PrepareThreadForCodeFlushing(isolate, top);
1419 Code* code = it.frame()->unchecked_code();
1420 MarkBit code_bit = Marking::MarkBitFrom(code);
1421 collector_->MarkObject(it.frame()->unchecked_code(), code_bit);
1422 }
1423 } 1407 }
1424 1408
1425 private: 1409 private:
1426 MarkCompactCollector* collector_; 1410 MarkCompactCollector* collector_;
1427 }; 1411 };
1428 1412
1429 1413
1430 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor { 1414 class SharedFunctionInfoMarkingVisitor : public ObjectVisitor {
1431 public: 1415 public:
1432 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector) 1416 explicit SharedFunctionInfoMarkingVisitor(MarkCompactCollector* collector)
1433 : collector_(collector) {} 1417 : collector_(collector) {}
1434 1418
1435 void VisitPointers(Object** start, Object** end) { 1419 void VisitPointers(Object** start, Object** end) {
1436 for (Object** p = start; p < end; p++) VisitPointer(p); 1420 for (Object** p = start; p < end; p++) VisitPointer(p);
1437 } 1421 }
1438 1422
1439 void VisitPointer(Object** slot) { 1423 void VisitPointer(Object** slot) {
1440 Object* obj = *slot; 1424 Object* obj = *slot;
1441 if (obj->IsSharedFunctionInfo()) { 1425 if (obj->IsSharedFunctionInfo()) {
1442 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj); 1426 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(obj);
1443 MarkBit shared_mark = Marking::MarkBitFrom(shared); 1427 MarkBit shared_mark = Marking::MarkBitFrom(shared);
1444 MarkBit code_mark = Marking::MarkBitFrom(shared->unchecked_code()); 1428 MarkBit code_mark = Marking::MarkBitFrom(shared->code());
1445 collector_->MarkObject(shared->unchecked_code(), code_mark); 1429 collector_->MarkObject(shared->code(), code_mark);
1446 collector_->MarkObject(shared, shared_mark); 1430 collector_->MarkObject(shared, shared_mark);
1447 } 1431 }
1448 } 1432 }
1449 1433
1450 private: 1434 private:
1451 MarkCompactCollector* collector_; 1435 MarkCompactCollector* collector_;
1452 }; 1436 };
1453 1437
1454 1438
1439 void MarkCompactCollector::MarkInlinedFunctionsCode(Code* code) {
1440 // For optimized functions we should retain both non-optimized version
1441 // of it's code and non-optimized version of all inlined functions.
1442 // This is required to support bailing out from inlined code.
1443 DeoptimizationInputData* data =
1444 DeoptimizationInputData::cast(code->deoptimization_data());
1445
1446 FixedArray* literals = data->LiteralArray();
1447
1448 for (int i = 0, count = data->InlinedFunctionCount()->value();
1449 i < count;
1450 i++) {
1451 JSFunction* inlined = JSFunction::cast(literals->get(i));
1452 Code* inlined_code = inlined->shared()->code();
1453 MarkBit inlined_code_mark = Marking::MarkBitFrom(inlined_code);
1454 MarkObject(inlined_code, inlined_code_mark);
1455 }
1456 }
1457
1458
1459 void MarkCompactCollector::PrepareThreadForCodeFlushing(Isolate* isolate,
1460 ThreadLocalTop* top) {
1461 for (StackFrameIterator it(isolate, top); !it.done(); it.Advance()) {
1462 // Note: for the frame that has a pending lazy deoptimization
1463 // StackFrame::unchecked_code will return a non-optimized code object for
1464 // the outermost function and StackFrame::LookupCode will return
1465 // actual optimized code object.
1466 StackFrame* frame = it.frame();
1467 Code* code = frame->unchecked_code();
1468 MarkBit code_mark = Marking::MarkBitFrom(code);
1469 MarkObject(code, code_mark);
1470 if (frame->is_optimized()) {
1471 MarkInlinedFunctionsCode(frame->LookupCode());
1472 }
1473 }
1474 }
1475
1476
1455 void MarkCompactCollector::PrepareForCodeFlushing() { 1477 void MarkCompactCollector::PrepareForCodeFlushing() {
1456 ASSERT(heap() == Isolate::Current()->heap()); 1478 ASSERT(heap() == Isolate::Current()->heap());
1457 1479
1458 // TODO(1609) Currently incremental marker does not support code flushing. 1480 // TODO(1609) Currently incremental marker does not support code flushing.
1459 if (!FLAG_flush_code || was_marked_incrementally_) { 1481 if (!FLAG_flush_code || was_marked_incrementally_) {
1460 EnableCodeFlushing(false); 1482 EnableCodeFlushing(false);
1461 return; 1483 return;
1462 } 1484 }
1463 1485
1464 #ifdef ENABLE_DEBUGGER_SUPPORT 1486 #ifdef ENABLE_DEBUGGER_SUPPORT
1465 if (heap()->isolate()->debug()->IsLoaded() || 1487 if (heap()->isolate()->debug()->IsLoaded() ||
1466 heap()->isolate()->debug()->has_break_points()) { 1488 heap()->isolate()->debug()->has_break_points()) {
1467 EnableCodeFlushing(false); 1489 EnableCodeFlushing(false);
1468 return; 1490 return;
1469 } 1491 }
1470 #endif 1492 #endif
1471 1493
1472 EnableCodeFlushing(true); 1494 EnableCodeFlushing(true);
1473 1495
1474 // Ensure that empty descriptor array is marked. Method MarkDescriptorArray 1496 // Ensure that empty descriptor array is marked. Method MarkDescriptorArray
1475 // relies on it being marked before any other descriptor array. 1497 // relies on it being marked before any other descriptor array.
1476 HeapObject* descriptor_array = heap()->empty_descriptor_array(); 1498 HeapObject* descriptor_array = heap()->empty_descriptor_array();
1477 MarkBit descriptor_array_mark = Marking::MarkBitFrom(descriptor_array); 1499 MarkBit descriptor_array_mark = Marking::MarkBitFrom(descriptor_array);
1478 MarkObject(descriptor_array, descriptor_array_mark); 1500 MarkObject(descriptor_array, descriptor_array_mark);
1479 1501
1480 // Make sure we are not referencing the code from the stack. 1502 // Make sure we are not referencing the code from the stack.
1481 ASSERT(this == heap()->mark_compact_collector()); 1503 ASSERT(this == heap()->mark_compact_collector());
1482 for (StackFrameIterator it; !it.done(); it.Advance()) { 1504 PrepareThreadForCodeFlushing(heap()->isolate(),
1483 Code* code = it.frame()->unchecked_code(); 1505 heap()->isolate()->thread_local_top());
1484 MarkBit code_mark = Marking::MarkBitFrom(code);
1485 MarkObject(code, code_mark);
1486 }
1487 1506
1488 // Iterate the archived stacks in all threads to check if 1507 // Iterate the archived stacks in all threads to check if
1489 // the code is referenced. 1508 // the code is referenced.
1490 CodeMarkingVisitor code_marking_visitor(this); 1509 CodeMarkingVisitor code_marking_visitor(this);
1491 heap()->isolate()->thread_manager()->IterateArchivedThreads( 1510 heap()->isolate()->thread_manager()->IterateArchivedThreads(
1492 &code_marking_visitor); 1511 &code_marking_visitor);
1493 1512
1494 SharedFunctionInfoMarkingVisitor visitor(this); 1513 SharedFunctionInfoMarkingVisitor visitor(this);
1495 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor); 1514 heap()->isolate()->compilation_cache()->IterateFunctions(&visitor);
1496 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor); 1515 heap()->isolate()->handle_scope_implementer()->Iterate(&visitor);
(...skipping 2388 matching lines...) Expand 10 before | Expand all | Expand 10 after
3885 while (buffer != NULL) { 3904 while (buffer != NULL) {
3886 SlotsBuffer* next_buffer = buffer->next(); 3905 SlotsBuffer* next_buffer = buffer->next();
3887 DeallocateBuffer(buffer); 3906 DeallocateBuffer(buffer);
3888 buffer = next_buffer; 3907 buffer = next_buffer;
3889 } 3908 }
3890 *buffer_address = NULL; 3909 *buffer_address = NULL;
3891 } 3910 }
3892 3911
3893 3912
3894 } } // namespace v8::internal 3913 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/mark-compact.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698