| 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 |