OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 intptr_t idx_; | 399 intptr_t idx_; |
400 intptr_t chain_length_; | 400 intptr_t chain_length_; |
401 SlotsBuffer* next_; | 401 SlotsBuffer* next_; |
402 ObjectSlot slots_[kNumberOfElements]; | 402 ObjectSlot slots_[kNumberOfElements]; |
403 }; | 403 }; |
404 | 404 |
405 | 405 |
406 // CodeFlusher collects candidates for code flushing during marking and | 406 // CodeFlusher collects candidates for code flushing during marking and |
407 // processes those candidates after marking has completed in order to | 407 // processes those candidates after marking has completed in order to |
408 // reset those functions referencing code objects that would otherwise | 408 // reset those functions referencing code objects that would otherwise |
409 // be unreachable. Code objects can be referenced in two ways: | 409 // be unreachable. Code objects can be referenced in three ways: |
410 // - SharedFunctionInfo references unoptimized code. | 410 // - SharedFunctionInfo references unoptimized code. |
411 // - JSFunction references either unoptimized or optimized code. | 411 // - JSFunction references either unoptimized or optimized code. |
| 412 // - OptimizedCodeMap references optimized code. |
412 // We are not allowed to flush unoptimized code for functions that got | 413 // We are not allowed to flush unoptimized code for functions that got |
413 // optimized or inlined into optimized code, because we might bailout | 414 // optimized or inlined into optimized code, because we might bailout |
414 // into the unoptimized code again during deoptimization. | 415 // into the unoptimized code again during deoptimization. |
415 class CodeFlusher { | 416 class CodeFlusher { |
416 public: | 417 public: |
417 explicit CodeFlusher(Isolate* isolate) | 418 explicit CodeFlusher(Isolate* isolate) |
418 : isolate_(isolate), | 419 : isolate_(isolate), |
419 jsfunction_candidates_head_(NULL), | 420 jsfunction_candidates_head_(NULL), |
420 shared_function_info_candidates_head_(NULL) {} | 421 shared_function_info_candidates_head_(NULL), |
| 422 optimized_code_map_holder_head_(NULL) {} |
421 | 423 |
422 void AddCandidate(SharedFunctionInfo* shared_info) { | 424 void AddCandidate(SharedFunctionInfo* shared_info) { |
423 if (GetNextCandidate(shared_info) == NULL) { | 425 if (GetNextCandidate(shared_info) == NULL) { |
424 SetNextCandidate(shared_info, shared_function_info_candidates_head_); | 426 SetNextCandidate(shared_info, shared_function_info_candidates_head_); |
425 shared_function_info_candidates_head_ = shared_info; | 427 shared_function_info_candidates_head_ = shared_info; |
426 } | 428 } |
427 } | 429 } |
428 | 430 |
429 void AddCandidate(JSFunction* function) { | 431 void AddCandidate(JSFunction* function) { |
430 ASSERT(function->code() == function->shared()->code()); | 432 ASSERT(function->code() == function->shared()->code()); |
431 if (GetNextCandidate(function)->IsUndefined()) { | 433 if (GetNextCandidate(function)->IsUndefined()) { |
432 SetNextCandidate(function, jsfunction_candidates_head_); | 434 SetNextCandidate(function, jsfunction_candidates_head_); |
433 jsfunction_candidates_head_ = function; | 435 jsfunction_candidates_head_ = function; |
434 } | 436 } |
435 } | 437 } |
436 | 438 |
| 439 void AddOptimizedCodeMap(SharedFunctionInfo* code_map_holder) { |
| 440 if (GetNextCodeMap(code_map_holder)->IsUndefined()) { |
| 441 SetNextCodeMap(code_map_holder, optimized_code_map_holder_head_); |
| 442 optimized_code_map_holder_head_ = code_map_holder; |
| 443 } |
| 444 } |
| 445 |
| 446 void EvictOptimizedCodeMap(SharedFunctionInfo* code_map_holder); |
437 void EvictCandidate(SharedFunctionInfo* shared_info); | 447 void EvictCandidate(SharedFunctionInfo* shared_info); |
438 void EvictCandidate(JSFunction* function); | 448 void EvictCandidate(JSFunction* function); |
439 | 449 |
440 void ProcessCandidates() { | 450 void ProcessCandidates() { |
| 451 ProcessOptimizedCodeMaps(); |
441 ProcessSharedFunctionInfoCandidates(); | 452 ProcessSharedFunctionInfoCandidates(); |
442 ProcessJSFunctionCandidates(); | 453 ProcessJSFunctionCandidates(); |
443 } | 454 } |
444 | 455 |
445 void EvictAllCandidates() { | 456 void EvictAllCandidates() { |
| 457 EvictOptimizedCodeMaps(); |
446 EvictJSFunctionCandidates(); | 458 EvictJSFunctionCandidates(); |
447 EvictSharedFunctionInfoCandidates(); | 459 EvictSharedFunctionInfoCandidates(); |
448 } | 460 } |
449 | 461 |
450 void IteratePointersToFromSpace(ObjectVisitor* v); | 462 void IteratePointersToFromSpace(ObjectVisitor* v); |
451 | 463 |
452 private: | 464 private: |
| 465 void ProcessOptimizedCodeMaps(); |
453 void ProcessJSFunctionCandidates(); | 466 void ProcessJSFunctionCandidates(); |
454 void ProcessSharedFunctionInfoCandidates(); | 467 void ProcessSharedFunctionInfoCandidates(); |
| 468 void EvictOptimizedCodeMaps(); |
455 void EvictJSFunctionCandidates(); | 469 void EvictJSFunctionCandidates(); |
456 void EvictSharedFunctionInfoCandidates(); | 470 void EvictSharedFunctionInfoCandidates(); |
457 | 471 |
458 static JSFunction** GetNextCandidateSlot(JSFunction* candidate) { | 472 static JSFunction** GetNextCandidateSlot(JSFunction* candidate) { |
459 return reinterpret_cast<JSFunction**>( | 473 return reinterpret_cast<JSFunction**>( |
460 HeapObject::RawField(candidate, JSFunction::kNextFunctionLinkOffset)); | 474 HeapObject::RawField(candidate, JSFunction::kNextFunctionLinkOffset)); |
461 } | 475 } |
462 | 476 |
463 static JSFunction* GetNextCandidate(JSFunction* candidate) { | 477 static JSFunction* GetNextCandidate(JSFunction* candidate) { |
464 Object* next_candidate = candidate->next_function_link(); | 478 Object* next_candidate = candidate->next_function_link(); |
(...skipping 17 matching lines...) Expand all Loading... |
482 | 496 |
483 static void SetNextCandidate(SharedFunctionInfo* candidate, | 497 static void SetNextCandidate(SharedFunctionInfo* candidate, |
484 SharedFunctionInfo* next_candidate) { | 498 SharedFunctionInfo* next_candidate) { |
485 candidate->code()->set_gc_metadata(next_candidate); | 499 candidate->code()->set_gc_metadata(next_candidate); |
486 } | 500 } |
487 | 501 |
488 static void ClearNextCandidate(SharedFunctionInfo* candidate) { | 502 static void ClearNextCandidate(SharedFunctionInfo* candidate) { |
489 candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER); | 503 candidate->code()->set_gc_metadata(NULL, SKIP_WRITE_BARRIER); |
490 } | 504 } |
491 | 505 |
| 506 static SharedFunctionInfo* GetNextCodeMap(SharedFunctionInfo* holder) { |
| 507 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
| 508 Object* next_map = code_map->get(SharedFunctionInfo::kNextMapIndex); |
| 509 return reinterpret_cast<SharedFunctionInfo*>(next_map); |
| 510 } |
| 511 |
| 512 static void SetNextCodeMap(SharedFunctionInfo* holder, |
| 513 SharedFunctionInfo* next_holder) { |
| 514 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
| 515 code_map->set(SharedFunctionInfo::kNextMapIndex, next_holder); |
| 516 } |
| 517 |
| 518 static void ClearNextCodeMap(SharedFunctionInfo* holder) { |
| 519 FixedArray* code_map = FixedArray::cast(holder->optimized_code_map()); |
| 520 code_map->set_undefined(SharedFunctionInfo::kNextMapIndex); |
| 521 } |
| 522 |
492 Isolate* isolate_; | 523 Isolate* isolate_; |
493 JSFunction* jsfunction_candidates_head_; | 524 JSFunction* jsfunction_candidates_head_; |
494 SharedFunctionInfo* shared_function_info_candidates_head_; | 525 SharedFunctionInfo* shared_function_info_candidates_head_; |
| 526 SharedFunctionInfo* optimized_code_map_holder_head_; |
495 | 527 |
496 DISALLOW_COPY_AND_ASSIGN(CodeFlusher); | 528 DISALLOW_COPY_AND_ASSIGN(CodeFlusher); |
497 }; | 529 }; |
498 | 530 |
499 | 531 |
500 // Defined in isolate.h. | 532 // Defined in isolate.h. |
501 class ThreadLocalTop; | 533 class ThreadLocalTop; |
502 | 534 |
503 | 535 |
504 // ------------------------------------------------------------------------- | 536 // ------------------------------------------------------------------------- |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 private: | 954 private: |
923 MarkCompactCollector* collector_; | 955 MarkCompactCollector* collector_; |
924 }; | 956 }; |
925 | 957 |
926 | 958 |
927 const char* AllocationSpaceName(AllocationSpace space); | 959 const char* AllocationSpaceName(AllocationSpace space); |
928 | 960 |
929 } } // namespace v8::internal | 961 } } // namespace v8::internal |
930 | 962 |
931 #endif // V8_MARK_COMPACT_H_ | 963 #endif // V8_MARK_COMPACT_H_ |
OLD | NEW |