// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/weak_code.h"

#include "platform/assert.h"

#include "vm/code_patcher.h"
#include "vm/object.h"
#include "vm/runtime_entry.h"
#include "vm/stack_frame.h"

namespace dart {

bool WeakCodeReferences::HasCodes() const {
  return !array_.IsNull() && (array_.Length() > 0);
}

void WeakCodeReferences::Register(const Code& value) {
  if (!array_.IsNull()) {
    // Try to find and reuse cleared WeakProperty to avoid allocating new one.
    WeakProperty& weak_property = WeakProperty::Handle();
    for (intptr_t i = 0; i < array_.Length(); i++) {
      weak_property ^= array_.At(i);
      if (weak_property.key() == Code::null()) {
        // Empty property found. Reuse it.
        weak_property.set_key(value);
        return;
      }
    }
  }

  const WeakProperty& weak_property =
      WeakProperty::Handle(WeakProperty::New(Heap::kOld));
  weak_property.set_key(value);

  intptr_t length = array_.IsNull() ? 0 : array_.Length();
  const Array& new_array =
      Array::Handle(Array::Grow(array_, length + 1, Heap::kOld));
  new_array.SetAt(length, weak_property);
  UpdateArrayTo(new_array);
}

bool WeakCodeReferences::IsOptimizedCode(const Array& dependent_code,
                                         const Code& code) {
  if (!code.is_optimized()) {
    return false;
  }
  WeakProperty& weak_property = WeakProperty::Handle();
  for (intptr_t i = 0; i < dependent_code.Length(); i++) {
    weak_property ^= dependent_code.At(i);
    if (code.raw() == weak_property.key()) {
      return true;
    }
  }
  return false;
}

void WeakCodeReferences::DisableCode() {
  Thread* thread = Thread::Current();
  const Array& code_objects = Array::Handle(thread->zone(), array_.raw());
#if defined(DART_PRECOMPILED_RUNTIME)
  ASSERT(code_objects.IsNull());
  return;
#else
  if (code_objects.IsNull()) {
    return;
  }

  UpdateArrayTo(Object::null_array());
  // Disable all code on stack.
  Code& code = Code::Handle();
  {
    DartFrameIterator iterator(thread,
                               StackFrameIterator::kNoCrossThreadIteration);
    StackFrame* frame = iterator.NextFrame();
    while (frame != NULL) {
      code = frame->LookupDartCode();
      if (IsOptimizedCode(code_objects, code)) {
        ReportDeoptimization(code);
        DeoptimizeAt(code, frame);
      }
      frame = iterator.NextFrame();
    }
  }

  // Switch functions that use dependent code to unoptimized code.
  WeakProperty& weak_property = WeakProperty::Handle();
  Object& owner = Object::Handle();
  Function& function = Function::Handle();
  for (intptr_t i = 0; i < code_objects.Length(); i++) {
    weak_property ^= code_objects.At(i);
    code ^= weak_property.key();
    if (code.IsNull()) {
      // Code was garbage collected already.
      continue;
    }
    owner = code.owner();
    if (owner.IsFunction()) {
      function ^= owner.raw();
    } else if (owner.IsClass()) {
      Class& cls = Class::Handle();
      cls ^= owner.raw();
      cls.DisableAllocationStub();
      continue;
    } else if (owner.IsNull()) {
      code.Print();
      continue;
    }

    // If function uses dependent code switch it to unoptimized.
    if (code.is_optimized() && (function.CurrentCode() == code.raw())) {
      ReportSwitchingCode(code);
      function.SwitchToUnoptimizedCode();
    } else if (function.unoptimized_code() == code.raw()) {
      ReportSwitchingCode(code);
      function.SetWasCompiled(false);
      function.ClearICDataArray();
      // Remove the code object from the function. The next time the
      // function is invoked, it will be compiled again.
      function.ClearCode();
      // Invalidate the old code object so existing references to it
      // (from optimized code) will be patched when invoked.
      if (!code.IsDisabled()) {
        code.DisableDartCode();
      }
    } else {
      // Make non-OSR code non-entrant.
      if (!code.IsDisabled()) {
        ReportSwitchingCode(code);
        code.DisableDartCode();
      }
    }
  }
#endif  // defined(DART_PRECOMPILED_RUNTIME)
}

}  // namespace dart
