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

Side by Side Diff: runtime/vm/object.cc

Issue 150923002: Mark optimized code that used CHA for optimization so that lazy class 'finalization' does not inval… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 2316 matching lines...) Expand 10 before | Expand all | Expand 10 after
2327 // Prefinalized classes have a VM internal representation and no Dart fields. 2327 // Prefinalized classes have a VM internal representation and no Dart fields.
2328 // Their instance size is precomputed and field offsets are known. 2328 // Their instance size is precomputed and field offsets are known.
2329 if (!is_prefinalized()) { 2329 if (!is_prefinalized()) {
2330 // Compute offsets of instance fields and instance size. 2330 // Compute offsets of instance fields and instance size.
2331 CalculateFieldOffsets(); 2331 CalculateFieldOffsets();
2332 } 2332 }
2333 set_is_finalized(); 2333 set_is_finalized();
2334 } 2334 }
2335 2335
2336 2336
2337 // Helper class to handle an array of code weak properties. Implements
2338 // registration and disabling of stored code objects.
2339 class WeakCodeReferences : public ValueObject {
Florian Schneider 2014/02/05 10:36:31 This class and it's two subclasses seem good candi
srdjan 2014/02/05 16:20:51 Templates are hard to work with: harder on compile
Florian Schneider 2014/02/05 17:07:28 I don't really care that much - so land it either
2340 public:
2341 explicit WeakCodeReferences(const Array& value) : array_(value) {}
Florian Schneider 2014/02/05 10:36:31 explicit WeakCodeReferences(const T& owner) :
2342 virtual ~WeakCodeReferences() {}
2343
2344 void Register(const Code& value) {
2345 if (!array_.IsNull()) {
2346 // Try to find and reuse cleared WeakProperty to avoid allocating new one.
2347 WeakProperty& weak_property = WeakProperty::Handle();
2348 for (intptr_t i = 0; i < array_.Length(); i++) {
2349 weak_property ^= array_.At(i);
2350 if (weak_property.key() == Code::null()) {
2351 // Empty property found. Reuse it.
2352 weak_property.set_key(value);
2353 return;
2354 }
2355 }
2356 }
2357
2358 const WeakProperty& weak_property = WeakProperty::Handle(
2359 WeakProperty::New(Heap::kOld));
2360 weak_property.set_key(value);
2361
2362 intptr_t length = array_.IsNull() ? 0 : array_.Length();
2363 const Array& new_array = Array::Handle(
2364 Array::Grow(array_, length + 1, Heap::kOld));
2365 new_array.SetAt(length, weak_property);
2366 UpdateArrayTo(new_array);
2367 }
2368
2369 virtual void UpdateArrayTo(const Array& array) = 0;
Florian Schneider 2014/02/05 10:36:31 void UpdateArrayTo(const Array& array) { owner_.
2370 virtual void ReportDeoptimization(const Code& code) = 0;
2371 virtual void ReportSwitchingCode(const Code& code) = 0;
2372
2373 static bool IsOptimizedCode(const Array& dependent_code, const Code& code) {
Florian Schneider 2014/02/05 17:07:28 This checks for two things: the code is optimized
2374 if (!code.is_optimized()) {
2375 return false;
2376 }
2377 WeakProperty& weak_property = WeakProperty::Handle();
2378 for (intptr_t i = 0; i < dependent_code.Length(); i++) {
2379 weak_property ^= dependent_code.At(i);
2380 if (code.raw() == weak_property.key()) {
2381 return true;
2382 }
2383 }
2384 return false;
2385 }
2386
2387 void DisableCode() {
2388 const Array& code_objects = Array::Handle(array_.raw());
2389 if (code_objects.IsNull()) {
2390 return;
2391 }
2392 UpdateArrayTo(Object::null_array());
2393 // Disable all code on stack.
2394 Code& code = Code::Handle();
2395 {
2396 DartFrameIterator iterator;
2397 StackFrame* frame = iterator.NextFrame();
2398 while (frame != NULL) {
2399 code = frame->LookupDartCode();
2400 if (IsOptimizedCode(code_objects, code)) {
2401 ReportDeoptimization(code);
2402 DeoptimizeAt(code, frame->pc());
2403 }
2404 frame = iterator.NextFrame();
2405 }
2406 }
2407
2408 // Switch functions that use dependent code to unoptimized code.
2409 WeakProperty& weak_property = WeakProperty::Handle();
2410 Function& function = Function::Handle();
2411 for (intptr_t i = 0; i < code_objects.Length(); i++) {
2412 weak_property ^= code_objects.At(i);
2413 code ^= weak_property.key();
2414 if (code.IsNull()) {
2415 // Code was garbage collected already.
2416 continue;
2417 }
2418
2419 function ^= code.function();
2420 // If function uses dependent code switch it to unoptimized.
2421 if (function.CurrentCode() == code.raw()) {
2422 ASSERT(function.HasOptimizedCode());
2423 ReportSwitchingCode(code);
2424 function.SwitchToUnoptimizedCode();
2425 }
2426 }
2427 }
2428
2429 private:
2430 const Array& array_;
Florian Schneider 2014/02/05 10:36:31 Replace array_ with owner_.dependent_code() in all
2431 DISALLOW_COPY_AND_ASSIGN(WeakCodeReferences);
2432 };
2433
2434
2435 class CHACodeArray : public WeakCodeReferences {
2436 public:
2437 explicit CHACodeArray(const Class& cls)
2438 : WeakCodeReferences(Array::Handle(cls.cha_codes())), cls_(cls) {
2439 }
2440
2441 virtual void UpdateArrayTo(const Array& value) {
2442 cls_.set_cha_codes(value);
2443 }
2444
2445 virtual void ReportDeoptimization(const Code& code) {
2446 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
2447 Function& function = Function::Handle(code.function());
2448 OS::PrintErr("Deoptimizing %s because CHA optimized (%s).\n",
2449 function.ToFullyQualifiedCString(),
2450 cls_.ToCString());
2451 }
2452 }
2453
2454 virtual void ReportSwitchingCode(const Code& code) {
2455 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
2456 Function& function = Function::Handle(code.function());
2457 OS::PrintErr("Switching %s to unoptimized code because CHA invalid"
2458 " (%s)\n",
2459 function.ToFullyQualifiedCString(),
2460 cls_.ToCString());
2461 }
2462 }
2463
2464 private:
2465 const Class& cls_;
2466 DISALLOW_COPY_AND_ASSIGN(CHACodeArray);
2467 };
2468
2469
2470 void Class::RegisterCHACode(const Code& code) {
2471 ASSERT(code.is_optimized());
2472 CHACodeArray a(*this);
2473 a.Register(code);
2474 }
2475
2476
2477 void Class::DisableCHAOptimizedCode() {
2478 CHACodeArray a(*this);
Florian Schneider 2014/02/05 10:36:31 WeakCodeReferences<Class> a(*this);
2479 a.DisableCode();
2480 }
2481
2482
2483 void Class::set_cha_codes(const Array& cache) const {
Florian Schneider 2014/02/05 10:36:31 s/set_cha_codes/set_dependent_code_/g s/cha_codes
srdjan 2014/02/05 16:20:51 Yes they would have 'compatible' interface but tha
Florian Schneider 2014/02/05 17:07:28 Imo, fragile would imply that something bad could
2484 StorePointer(&raw_ptr()->cha_codes_, cache.raw());
2485 }
2486
2487
2337 // Apply the members from the patch class to the original class. 2488 // Apply the members from the patch class to the original class.
2338 bool Class::ApplyPatch(const Class& patch, Error* error) const { 2489 bool Class::ApplyPatch(const Class& patch, Error* error) const {
2339 ASSERT(error != NULL); 2490 ASSERT(error != NULL);
2340 ASSERT(!is_finalized()); 2491 ASSERT(!is_finalized());
2341 // Shared handles used during the iteration. 2492 // Shared handles used during the iteration.
2342 String& member_name = String::Handle(); 2493 String& member_name = String::Handle();
2343 2494
2344 const PatchClass& patch_class = 2495 const PatchClass& patch_class =
2345 PatchClass::Handle(PatchClass::New(*this, patch)); 2496 PatchClass::Handle(PatchClass::New(*this, patch));
2346 2497
(...skipping 4039 matching lines...) Expand 10 before | Expand all | Expand 10 after
6386 } 6537 }
6387 } 6538 }
6388 6539
6389 6540
6390 RawArray* Field::dependent_code() const { 6541 RawArray* Field::dependent_code() const {
6391 return raw_ptr()->dependent_code_; 6542 return raw_ptr()->dependent_code_;
6392 } 6543 }
6393 6544
6394 6545
6395 void Field::set_dependent_code(const Array& array) const { 6546 void Field::set_dependent_code(const Array& array) const {
6396 raw_ptr()->dependent_code_ = array.raw(); 6547 StorePointer(&raw_ptr()->dependent_code_, array.raw());
6397 } 6548 }
6398 6549
6399 6550
6400 void Field::RegisterDependentCode(const Code& code) const { 6551 class FieldDependentArray : public WeakCodeReferences {
6401 const Array& dependent = Array::Handle(dependent_code()); 6552 public:
6553 explicit FieldDependentArray(const Field& field)
6554 : WeakCodeReferences(Array::Handle(field.dependent_code())),
6555 field_(field) {}
6402 6556
6403 if (!dependent.IsNull()) { 6557 virtual void UpdateArrayTo(const Array& value) {
6404 // Try to find and reuse cleared WeakProperty to avoid allocating new one. 6558 field_.set_dependent_code(value);
6405 WeakProperty& weak_property = WeakProperty::Handle(); 6559 }
6406 for (intptr_t i = 0; i < dependent.Length(); i++) { 6560
6407 weak_property ^= dependent.At(i); 6561 virtual void ReportDeoptimization(const Code& code) {
6408 if (weak_property.key() == Code::null()) { 6562 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
6409 // Empty property found. Reuse it. 6563 Function& function = Function::Handle(code.function());
6410 weak_property.set_key(code); 6564 OS::PrintErr("Deoptimizing %s because guard on field %s failed.\n",
6411 return; 6565 function.ToFullyQualifiedCString(),
6412 } 6566 field_.ToCString());
6413 } 6567 }
6414 } 6568 }
6415 6569
6416 const WeakProperty& weak_property = WeakProperty::Handle( 6570 virtual void ReportSwitchingCode(const Code& code) {
6417 WeakProperty::New(Heap::kOld)); 6571 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
6418 weak_property.set_key(code); 6572 Function& function = Function::Handle(code.function());
6419 6573 OS::PrintErr("Switching %s to unoptimized code because guard"
6420 intptr_t length = dependent.IsNull() ? 0 : dependent.Length(); 6574 " on field %s was violated.\n",
6421 const Array& new_dependent = Array::Handle( 6575 function.ToFullyQualifiedCString(),
6422 Array::Grow(dependent, length + 1, Heap::kOld)); 6576 field_.ToCString());
6423 new_dependent.SetAt(length, weak_property);
6424 set_dependent_code(new_dependent);
6425 }
6426
6427
6428 static bool IsDependentCode(const Array& dependent_code, const Code& code) {
6429 if (!code.is_optimized()) {
6430 return false;
6431 }
6432
6433 WeakProperty& weak_property = WeakProperty::Handle();
6434 for (intptr_t i = 0; i < dependent_code.Length(); i++) {
6435 weak_property ^= dependent_code.At(i);
6436 if (code.raw() == weak_property.key()) {
6437 return true;
6438 } 6577 }
6439 } 6578 }
6440 6579
6441 return false; 6580 private:
6581 const Field& field_;
6582 DISALLOW_COPY_AND_ASSIGN(FieldDependentArray);
6583 };
6584
6585
6586 void Field::RegisterDependentCode(const Code& code) const {
6587 ASSERT(code.is_optimized());
6588 FieldDependentArray a(*this);
6589 a.Register(code);
6442 } 6590 }
6443 6591
6444 6592
6445 void Field::DeoptimizeDependentCode() const { 6593 void Field::DeoptimizeDependentCode() const {
6446 const Array& code_objects = Array::Handle(dependent_code()); 6594 FieldDependentArray a(*this);
Florian Schneider 2014/02/05 10:36:31 WeakCodeReferences<Field> a(*this);
6447 6595 a.DisableCode();
6448 if (code_objects.IsNull()) {
6449 return;
6450 }
6451 set_dependent_code(Object::null_array());
6452
6453 // Deoptimize all dependent code on the stack.
6454 Code& code = Code::Handle();
6455 {
6456 DartFrameIterator iterator;
6457 StackFrame* frame = iterator.NextFrame();
6458 while (frame != NULL) {
6459 code = frame->LookupDartCode();
6460 if (IsDependentCode(code_objects, code)) {
6461 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
6462 Function& function = Function::Handle(code.function());
6463 OS::PrintErr("Deoptimizing %s because guard on field %s failed.\n",
6464 function.ToFullyQualifiedCString(),
6465 ToCString());
6466 }
6467 DeoptimizeAt(code, frame->pc());
6468 }
6469 frame = iterator.NextFrame();
6470 }
6471 }
6472
6473 // Switch functions that use dependent code to unoptimized code.
6474 WeakProperty& weak_property = WeakProperty::Handle();
6475 Function& function = Function::Handle();
6476 for (intptr_t i = 0; i < code_objects.Length(); i++) {
6477 weak_property ^= code_objects.At(i);
6478 code ^= weak_property.key();
6479 if (code.IsNull()) {
6480 // Code was garbage collected already.
6481 continue;
6482 }
6483
6484 function ^= code.function();
6485 // If function uses dependent code switch it to unoptimized.
6486 if (function.CurrentCode() == code.raw()) {
6487 ASSERT(function.HasOptimizedCode());
6488 if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
6489 OS::PrintErr("Switching %s to unoptimized code because guard"
6490 " on field %s was violated.\n",
6491 function.ToFullyQualifiedCString(),
6492 ToCString());
6493 }
6494 function.SwitchToUnoptimizedCode();
6495 }
6496 }
6497 } 6596 }
6498 6597
6499 6598
6500 bool Field::IsUninitialized() const { 6599 bool Field::IsUninitialized() const {
6501 const Instance& value = Instance::Handle(raw_ptr()->value_); 6600 const Instance& value = Instance::Handle(raw_ptr()->value_);
6502 ASSERT(value.raw() != Object::transition_sentinel().raw()); 6601 ASSERT(value.raw() != Object::transition_sentinel().raw());
6503 return value.raw() == Object::sentinel().raw(); 6602 return value.raw() == Object::sentinel().raw();
6504 } 6603 }
6505 6604
6506 6605
(...skipping 10718 matching lines...) Expand 10 before | Expand all | Expand 10 after
17225 return "_MirrorReference"; 17324 return "_MirrorReference";
17226 } 17325 }
17227 17326
17228 17327
17229 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 17328 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
17230 Instance::PrintToJSONStream(stream, ref); 17329 Instance::PrintToJSONStream(stream, ref);
17231 } 17330 }
17232 17331
17233 17332
17234 } // namespace dart 17333 } // namespace dart
OLDNEW
« runtime/vm/isolate.h ('K') | « runtime/vm/object.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698