100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers/*
200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * Copyright (C) 2012 The Android Open Source Project
300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers *
400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * Licensed under the Apache License, Version 2.0 (the "License");
500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * you may not use this file except in compliance with the License.
600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * You may obtain a copy of the License at
700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers *
800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers *      http://www.apache.org/licenses/LICENSE-2.0
900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers *
1000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * Unless required by applicable law or agreed to in writing, software
1100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * distributed under the License is distributed on an "AS IS" BASIS,
1200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * See the License for the specific language governing permissions and
1400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers * limitations under the License.
1500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers */
1600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
1700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "jobject_comparator.h"
1800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/array-inl.h"
204f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "mirror/class-inl.h"
212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
220795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h"
2300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
2400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersnamespace art {
2500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
2600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogersbool JobjectComparator::operator()(jobject jobj1, jobject jobj2) const {
2700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Ensure null references and cleared jweaks appear at the end.
284c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  if (jobj1 == nullptr) {
2900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
304c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  } else if (jobj2 == nullptr) {
3100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return false;
3200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
3300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  ScopedObjectAccess soa(Thread::Current());
344c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  StackHandleScope<2> hs(soa.Self());
350795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier  Handle<mirror::Object> obj1(hs.NewHandle(soa.Decode<mirror::Object>(jobj1)));
360795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier  Handle<mirror::Object> obj2(hs.NewHandle(soa.Decode<mirror::Object>(jobj2)));
37fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe  if (obj1 == nullptr) {
3800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return true;
39fa4333dcb481e564f54726b4e6f8153612df835eAndreas Gampe  } else if (obj2 == nullptr) {
4000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers    return false;
4100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
4200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  // Sort by class...
4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  if (obj1->GetClass() != obj2->GetClass()) {
443096bc5d80a609c5e1c80ce64eeb6f3299ee4012Mathieu Chartier    return obj1->GetClass()->IdentityHashCode() < obj2->GetClass()->IdentityHashCode();
4500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers  }
464c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  // ...then by size...
474c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  const size_t count1 = obj1->SizeOf();
484c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  const size_t count2 = obj2->SizeOf();
494c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  if (count1 != count2) {
504c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier    return count1 < count2;
514c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  }
524c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  // ...and finally by identity hash code.
534c4d609a3f1d67c76c855df13c2c1be9c315a6c9Mathieu Chartier  return obj1->IdentityHashCode() < obj2->IdentityHashCode();
5400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}
5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers
5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers}  // namespace art
57