OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <iomanip> | 5 #include <iomanip> |
6 #include <sstream> | 6 #include <sstream> |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
(...skipping 11298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11309 PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge, NO_MARKING_PARITY); | 11309 PatchPlatformCodeAge(isolate, sequence, kNoAgeCodeAge, NO_MARKING_PARITY); |
11310 } | 11310 } |
11311 | 11311 |
11312 | 11312 |
11313 void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) { | 11313 void Code::MarkCodeAsExecuted(byte* sequence, Isolate* isolate) { |
11314 PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge, | 11314 PatchPlatformCodeAge(isolate, sequence, kExecutedOnceCodeAge, |
11315 NO_MARKING_PARITY); | 11315 NO_MARKING_PARITY); |
11316 } | 11316 } |
11317 | 11317 |
11318 | 11318 |
11319 static Code::Age EffectiveAge(Code::Age age) { | 11319 // NextAge defines the Code::Age state transitions during a GC cycle. |
11320 if (age == Code::kNotExecutedCodeAge) { | 11320 static Code::Age NextAge(Code::Age age) { |
11321 // Treat that's never been executed as old immediately. | 11321 switch (age) { |
11322 age = Code::kIsOldCodeAge; | 11322 case Code::kNotExecutedCodeAge: // Keep, until we've been executed. |
11323 } else if (age == Code::kExecutedOnceCodeAge) { | 11323 case Code::kToBeExecutedOnceCodeAge: // Keep, until we've been executed. |
11324 // Pre-age code that has only been executed once. | 11324 case Code::kLastCodeAge: // Clamp at last Code::Age value. |
11325 age = Code::kPreAgedCodeAge; | 11325 return age; |
| 11326 case Code::kExecutedOnceCodeAge: |
| 11327 // Pre-age code that has only been executed once. |
| 11328 return static_cast<Code::Age>(Code::kPreAgedCodeAge + 1); |
| 11329 default: |
| 11330 return static_cast<Code::Age>(age + 1); // Default case: Increase age. |
11326 } | 11331 } |
11327 return age; | |
11328 } | 11332 } |
11329 | 11333 |
11330 | 11334 |
| 11335 // IsOldAge defines the collection criteria for a Code object. |
| 11336 static bool IsOldAge(Code::Age age) { |
| 11337 return age >= Code::kIsOldCodeAge || age == Code::kNotExecutedCodeAge; |
| 11338 } |
| 11339 |
| 11340 |
11331 void Code::MakeYoung(Isolate* isolate) { | 11341 void Code::MakeYoung(Isolate* isolate) { |
11332 byte* sequence = FindCodeAgeSequence(); | 11342 byte* sequence = FindCodeAgeSequence(); |
11333 if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate); | 11343 if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate); |
11334 } | 11344 } |
11335 | 11345 |
11336 | 11346 |
| 11347 void Code::MarkToBeExecutedOnce(Isolate* isolate) { |
| 11348 byte* sequence = FindCodeAgeSequence(); |
| 11349 if (sequence != NULL) { |
| 11350 PatchPlatformCodeAge(isolate, sequence, kToBeExecutedOnceCodeAge, |
| 11351 NO_MARKING_PARITY); |
| 11352 } |
| 11353 } |
| 11354 |
| 11355 |
11337 void Code::MakeOlder(MarkingParity current_parity) { | 11356 void Code::MakeOlder(MarkingParity current_parity) { |
11338 byte* sequence = FindCodeAgeSequence(); | 11357 byte* sequence = FindCodeAgeSequence(); |
11339 if (sequence != NULL) { | 11358 if (sequence != NULL) { |
11340 Age age; | 11359 Age age; |
11341 MarkingParity code_parity; | 11360 MarkingParity code_parity; |
11342 Isolate* isolate = GetIsolate(); | 11361 Isolate* isolate = GetIsolate(); |
11343 GetCodeAgeAndParity(isolate, sequence, &age, &code_parity); | 11362 GetCodeAgeAndParity(isolate, sequence, &age, &code_parity); |
11344 age = EffectiveAge(age); | 11363 Age next_age = NextAge(age); |
11345 if (age != kLastCodeAge && code_parity != current_parity) { | 11364 if (age != next_age && code_parity != current_parity) { |
11346 PatchPlatformCodeAge(isolate, | 11365 PatchPlatformCodeAge(isolate, sequence, next_age, current_parity); |
11347 sequence, | |
11348 static_cast<Age>(age + 1), | |
11349 current_parity); | |
11350 } | 11366 } |
11351 } | 11367 } |
11352 } | 11368 } |
11353 | 11369 |
11354 | 11370 |
11355 bool Code::IsOld() { | 11371 bool Code::IsOld() { |
11356 return GetAge() >= kIsOldCodeAge; | 11372 return IsOldAge(GetAge()); |
11357 } | 11373 } |
11358 | 11374 |
11359 | 11375 |
11360 byte* Code::FindCodeAgeSequence() { | 11376 byte* Code::FindCodeAgeSequence() { |
11361 return FLAG_age_code && | 11377 return FLAG_age_code && |
11362 prologue_offset() != Code::kPrologueOffsetNotSet && | 11378 prologue_offset() != Code::kPrologueOffsetNotSet && |
11363 (kind() == OPTIMIZED_FUNCTION || | 11379 (kind() == OPTIMIZED_FUNCTION || |
11364 (kind() == FUNCTION && !has_debug_break_slots())) | 11380 (kind() == FUNCTION && !has_debug_break_slots())) |
11365 ? instruction_start() + prologue_offset() | 11381 ? instruction_start() + prologue_offset() |
11366 : NULL; | 11382 : NULL; |
11367 } | 11383 } |
11368 | 11384 |
11369 | 11385 |
11370 Code::Age Code::GetAge() { | 11386 Code::Age Code::GetAge() { |
11371 return EffectiveAge(GetRawAge()); | |
11372 } | |
11373 | |
11374 | |
11375 Code::Age Code::GetRawAge() { | |
11376 byte* sequence = FindCodeAgeSequence(); | 11387 byte* sequence = FindCodeAgeSequence(); |
11377 if (sequence == NULL) { | 11388 if (sequence == NULL) { |
11378 return kNoAgeCodeAge; | 11389 return kNoAgeCodeAge; |
11379 } | 11390 } |
11380 Age age; | 11391 Age age; |
11381 MarkingParity parity; | 11392 MarkingParity parity; |
11382 GetCodeAgeAndParity(GetIsolate(), sequence, &age, &parity); | 11393 GetCodeAgeAndParity(GetIsolate(), sequence, &age, &parity); |
11383 return age; | 11394 return age; |
11384 } | 11395 } |
11385 | 11396 |
(...skipping 23 matching lines...) Expand all Loading... |
11409 *age = kNotExecutedCodeAge; | 11420 *age = kNotExecutedCodeAge; |
11410 *parity = NO_MARKING_PARITY; | 11421 *parity = NO_MARKING_PARITY; |
11411 return; | 11422 return; |
11412 } | 11423 } |
11413 stub = *builtins->MarkCodeAsExecutedTwice(); | 11424 stub = *builtins->MarkCodeAsExecutedTwice(); |
11414 if (code == stub) { | 11425 if (code == stub) { |
11415 *age = kExecutedOnceCodeAge; | 11426 *age = kExecutedOnceCodeAge; |
11416 *parity = NO_MARKING_PARITY; | 11427 *parity = NO_MARKING_PARITY; |
11417 return; | 11428 return; |
11418 } | 11429 } |
| 11430 stub = *builtins->MarkCodeAsToBeExecutedOnce(); |
| 11431 if (code == stub) { |
| 11432 *age = kToBeExecutedOnceCodeAge; |
| 11433 *parity = NO_MARKING_PARITY; |
| 11434 return; |
| 11435 } |
11419 UNREACHABLE(); | 11436 UNREACHABLE(); |
11420 } | 11437 } |
11421 | 11438 |
11422 | 11439 |
11423 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { | 11440 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { |
11424 Builtins* builtins = isolate->builtins(); | 11441 Builtins* builtins = isolate->builtins(); |
11425 switch (age) { | 11442 switch (age) { |
11426 #define HANDLE_CODE_AGE(AGE) \ | 11443 #define HANDLE_CODE_AGE(AGE) \ |
11427 case k##AGE##CodeAge: { \ | 11444 case k##AGE##CodeAge: { \ |
11428 Code* stub = parity == EVEN_MARKING_PARITY \ | 11445 Code* stub = parity == EVEN_MARKING_PARITY \ |
11429 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ | 11446 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ |
11430 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ | 11447 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ |
11431 return stub; \ | 11448 return stub; \ |
11432 } | 11449 } |
11433 CODE_AGE_LIST(HANDLE_CODE_AGE) | 11450 CODE_AGE_LIST(HANDLE_CODE_AGE) |
11434 #undef HANDLE_CODE_AGE | 11451 #undef HANDLE_CODE_AGE |
11435 case kNotExecutedCodeAge: { | 11452 case kNotExecutedCodeAge: { |
11436 DCHECK(parity == NO_MARKING_PARITY); | 11453 DCHECK(parity == NO_MARKING_PARITY); |
11437 return *builtins->MarkCodeAsExecutedOnce(); | 11454 return *builtins->MarkCodeAsExecutedOnce(); |
11438 } | 11455 } |
11439 case kExecutedOnceCodeAge: { | 11456 case kExecutedOnceCodeAge: { |
11440 DCHECK(parity == NO_MARKING_PARITY); | 11457 DCHECK(parity == NO_MARKING_PARITY); |
11441 return *builtins->MarkCodeAsExecutedTwice(); | 11458 return *builtins->MarkCodeAsExecutedTwice(); |
11442 } | 11459 } |
| 11460 case kToBeExecutedOnceCodeAge: { |
| 11461 DCHECK(parity == NO_MARKING_PARITY); |
| 11462 return *builtins->MarkCodeAsToBeExecutedOnce(); |
| 11463 } |
11443 default: | 11464 default: |
11444 UNREACHABLE(); | 11465 UNREACHABLE(); |
11445 break; | 11466 break; |
11446 } | 11467 } |
11447 return NULL; | 11468 return NULL; |
11448 } | 11469 } |
11449 | 11470 |
11450 | 11471 |
11451 void Code::PrintDeoptLocation(FILE* out, Address pc) { | 11472 void Code::PrintDeoptLocation(FILE* out, Address pc) { |
11452 Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, pc); | 11473 Deoptimizer::DeoptInfo info = Deoptimizer::GetDeoptInfo(this, pc); |
(...skipping 5680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17133 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, | 17154 void PropertyCell::SetValueWithInvalidation(Handle<PropertyCell> cell, |
17134 Handle<Object> new_value) { | 17155 Handle<Object> new_value) { |
17135 if (cell->value() != *new_value) { | 17156 if (cell->value() != *new_value) { |
17136 cell->set_value(*new_value); | 17157 cell->set_value(*new_value); |
17137 Isolate* isolate = cell->GetIsolate(); | 17158 Isolate* isolate = cell->GetIsolate(); |
17138 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 17159 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
17139 isolate, DependentCode::kPropertyCellChangedGroup); | 17160 isolate, DependentCode::kPropertyCellChangedGroup); |
17140 } | 17161 } |
17141 } | 17162 } |
17142 } } // namespace v8::internal | 17163 } } // namespace v8::internal |
OLD | NEW |