1dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Copyright 2013 the V8 project authors. All rights reserved.
2dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Redistribution and use in source and binary forms, with or without
3dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// modification, are permitted provided that the following conditions are
4dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// met:
5dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//
6dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//     * Redistributions of source code must retain the above copyright
7dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//       notice, this list of conditions and the following disclaimer.
8dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//     * Redistributions in binary form must reproduce the above
9dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//       copyright notice, this list of conditions and the following
10dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//       disclaimer in the documentation and/or other materials provided
11dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//       with the distribution.
12dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//     * Neither the name of Google Inc. nor the names of its
13dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//       contributors may be used to endorse or promote products derived
14dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//       from this software without specific prior written permission.
15dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org//
16dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
28dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org#include "types.h"
29bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org#include "string-stream.h"
30dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
31dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgnamespace v8 {
32dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgnamespace internal {
33dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
3441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgint Type::NumClasses() {
3541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (is_class()) {
3641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return 1;
3741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else if (is_union()) {
3841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<Unioned> unioned = as_union();
3941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    int result = 0;
4041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
4141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (union_get(unioned, i)->is_class()) ++result;
4241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
4341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return result;
4441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else {
4541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return 0;
4641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
4741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
4841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
4941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
5041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgint Type::NumConstants() {
5141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (is_constant()) {
5241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return 1;
5341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else if (is_union()) {
5441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<Unioned> unioned = as_union();
5541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    int result = 0;
5641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
5741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (union_get(unioned, i)->is_constant()) ++result;
5841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
5941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return result;
6041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else {
6141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return 0;
6241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
6341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
6441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
6541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
6641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<class T>
6741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgHandle<Type> Type::Iterator<T>::get_type() {
6841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  ASSERT(!Done());
6941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return type_->is_union() ? union_get(type_->as_union(), index_) : type_;
7041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
7141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
7241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<>
73ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHandle<i::Map> Type::Iterator<i::Map>::Current() {
7441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return get_type()->as_class();
7541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
7641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
7741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<>
78ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgHandle<i::Object> Type::Iterator<i::Object>::Current() {
7941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return get_type()->as_constant();
8041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
8141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
8241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
8341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<>
84ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgbool Type::Iterator<i::Map>::matches(Handle<Type> type) {
8541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return type->is_class();
8641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
8741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
8841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<>
89ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgbool Type::Iterator<i::Object>::matches(Handle<Type> type) {
9041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  return type->is_constant();
9141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
9241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
9341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
9441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgtemplate<class T>
9541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgvoid Type::Iterator<T>::Advance() {
9641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  ++index_;
9741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  if (type_->is_union()) {
9841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    Handle<Unioned> unioned = type_->as_union();
9941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    for (; index_ < unioned->length(); ++index_) {
10041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org      if (matches(union_get(unioned, index_))) return;
10141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    }
10241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  } else if (index_ == 0 && matches(type_)) {
10341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return;
10441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  }
10541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  index_ = -1;
10641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org}
10741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
108ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgtemplate class Type::Iterator<i::Map>;
109ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgtemplate class Type::Iterator<i::Object>;
11041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
11141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org
112dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Get the smallest bitset subsuming this type.
113dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgint Type::LubBitset() {
114dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (this->is_bitset()) {
115dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return this->as_bitset();
116dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else if (this->is_union()) {
117dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Unioned> unioned = this->as_union();
118dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    int bitset = kNone;
119dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
120dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      bitset |= union_get(unioned, i)->LubBitset();
121dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
122dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return bitset;
123ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  } else if (this->is_class()) {
124ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    return LubBitset(*this->as_class());
125dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else {
126ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    return LubBitset(*this->as_constant());
127ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
128ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
129ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
130ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
131ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgint Type::LubBitset(i::Object* value) {
132ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (value->IsSmi()) return kSmi;
133ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  i::Map* map = i::HeapObject::cast(value)->map();
134ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (map->instance_type() == HEAP_NUMBER_TYPE) {
135ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    int32_t i;
136ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    uint32_t u;
137ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (value->ToInt32(&i)) return Smi::IsValid(i) ? kSmi : kOtherSigned32;
138ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (value->ToUint32(&u)) return kUnsigned32;
139ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    return kDouble;
140ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
141ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (map->instance_type() == ODDBALL_TYPE) {
142ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (value->IsUndefined()) return kUndefined;
143ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (value->IsNull()) return kNull;
144ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (value->IsBoolean()) return kBoolean;
145ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    if (value->IsTheHole()) return kAny;  // TODO(rossberg): kNone?
146ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    UNREACHABLE();
147ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
148ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  return Type::LubBitset(map);
149ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
150ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
151ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
152ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgint Type::LubBitset(i::Map* map) {
153ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  switch (map->instance_type()) {
154ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case STRING_TYPE:
155ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case ASCII_STRING_TYPE:
156ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case CONS_STRING_TYPE:
157ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case CONS_ASCII_STRING_TYPE:
158ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SLICED_STRING_TYPE:
159ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SLICED_ASCII_STRING_TYPE:
160ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXTERNAL_STRING_TYPE:
161ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXTERNAL_ASCII_STRING_TYPE:
162ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
163ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SHORT_EXTERNAL_STRING_TYPE:
164ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SHORT_EXTERNAL_ASCII_STRING_TYPE:
165ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SHORT_EXTERNAL_STRING_WITH_ONE_BYTE_DATA_TYPE:
166ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case INTERNALIZED_STRING_TYPE:
167ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case ASCII_INTERNALIZED_STRING_TYPE:
168ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case CONS_INTERNALIZED_STRING_TYPE:
169ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case CONS_ASCII_INTERNALIZED_STRING_TYPE:
170ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXTERNAL_INTERNALIZED_STRING_TYPE:
171ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
172ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
173ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE:
174ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SHORT_EXTERNAL_ASCII_INTERNALIZED_STRING_TYPE:
175ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SHORT_EXTERNAL_INTERNALIZED_STRING_WITH_ONE_BYTE_DATA_TYPE:
176ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kString;
177ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case SYMBOL_TYPE:
178ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kSymbol;
179ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case ODDBALL_TYPE:
180ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kOddball;
181ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case HEAP_NUMBER_TYPE:
182ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kDouble;
183ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_VALUE_TYPE:
184ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_DATE_TYPE:
185ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_OBJECT_TYPE:
186ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
187ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_GENERATOR_OBJECT_TYPE:
188ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_MODULE_TYPE:
189ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_GLOBAL_OBJECT_TYPE:
190ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_BUILTINS_OBJECT_TYPE:
191ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_GLOBAL_PROXY_TYPE:
192ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_ARRAY_BUFFER_TYPE:
193ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_TYPED_ARRAY_TYPE:
194ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_DATA_VIEW_TYPE:
195ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_SET_TYPE:
196ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_MAP_TYPE:
197ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_WEAK_MAP_TYPE:
198ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_WEAK_SET_TYPE:
199ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      if (map->is_undetectable()) return kUndetectable;
200ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kOtherObject;
201ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_ARRAY_TYPE:
202ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kArray;
203ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_FUNCTION_TYPE:
204ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kFunction;
205ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_REGEXP_TYPE:
206ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kRegExp;
207ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_PROXY_TYPE:
208ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case JS_FUNCTION_PROXY_TYPE:
209ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kProxy;
210ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case MAP_TYPE:
211ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // When compiling stub templates, the meta map is used as a place holder
212ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // for the actual map with which the template is later instantiated.
213ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // We treat it as a kind of type variable whose upper bound is Any.
214ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // TODO(rossberg): for caching of CompareNilIC stubs to work correctly,
215ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // we must exclude Undetectable here. This makes no sense, really,
216ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // because it means that the template isn't actually parametric.
217ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // Also, it doesn't apply elsewhere. 8-(
218ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // We ought to find a cleaner solution for compiling stubs parameterised
219ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      // over type or class variables, esp ones with bounds...
220ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kDetectable;
221ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case DECLARED_ACCESSOR_INFO_TYPE:
222ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case EXECUTABLE_ACCESSOR_INFO_TYPE:
223ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case ACCESSOR_PAIR_TYPE:
224ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    case FIXED_ARRAY_TYPE:
225ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kInternal;
226ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    default:
227ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      UNREACHABLE();
228ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      return kNone;
229dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
230dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
231dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
232dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
233dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Get the largest bitset subsumed by this type.
234dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgint Type::GlbBitset() {
235dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (this->is_bitset()) {
236dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return this->as_bitset();
237dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else if (this->is_union()) {
238dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    // All but the first are non-bitsets and thus would yield kNone anyway.
239dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return union_get(this->as_union(), 0)->GlbBitset();
240dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else {
241dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return kNone;
242dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
243dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
244dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
245dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
246ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org// Most precise _current_ type of a value (usually its class).
247f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgType* Type::OfCurrently(Handle<i::Object> value) {
248ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (value->IsSmi()) return Smi();
249ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  i::Map* map = i::HeapObject::cast(*value)->map();
250ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  if (map->instance_type() == HEAP_NUMBER_TYPE ||
251ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org      map->instance_type() == ODDBALL_TYPE) {
252ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    return Type::Of(value);
253ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  }
254ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org  return Class(i::handle(map));
255ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org}
256ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
257ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org
258dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Check this <= that.
259dd6d9eedcac6e3b5adfb7702649ac32def9c3585mvstanton@chromium.orgbool Type::SlowIs(Type* that) {
260dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // Fast path for bitsets.
261a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  if (this->is_none()) return true;
262dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (that->is_bitset()) {
263dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return (this->LubBitset() | that->as_bitset()) == that->as_bitset();
264dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
265dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
266dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (that->is_class()) {
267dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return this->is_class() && *this->as_class() == *that->as_class();
268dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
269dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (that->is_constant()) {
27041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org    return this->is_constant() && *this->as_constant() == *that->as_constant();
271dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
272dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
273dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // (T1 \/ ... \/ Tn) <= T  <=>  (T1 <= T) /\ ... /\ (Tn <= T)
274dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (this->is_union()) {
275dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Unioned> unioned = this->as_union();
276dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
277dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<Type> this_i = union_get(unioned, i);
278dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (!this_i->Is(that)) return false;
279dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
280dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return true;
281dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
282dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
283dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // T <= (T1 \/ ... \/ Tn)  <=>  (T <= T1) \/ ... \/ (T <= Tn)
284dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // (iff T is not a union)
2851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(!this->is_union());
286dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (that->is_union()) {
287dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Unioned> unioned = that->as_union();
288dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
289dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<Type> that_i = union_get(unioned, i);
290dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (this->Is(that_i)) return true;
291dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (this->is_bitset()) break;  // Fast fail, no other field is a bitset.
292dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
293dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return false;
294dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
295dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
296dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return false;
297dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
298dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
299dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
300f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgbool Type::IsCurrently(Type* that) {
301f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  return this->Is(that) ||
302f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      (this->is_constant() && that->is_class() &&
303f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org       this->as_constant()->IsHeapObject() &&
304f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org       i::HeapObject::cast(*this->as_constant())->map() == *that->as_class());
305f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
306f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
307f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
308dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Check this overlaps that.
30941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgbool Type::Maybe(Type* that) {
310dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // Fast path for bitsets.
311dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (this->is_bitset()) {
312dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return (this->as_bitset() & that->LubBitset()) != 0;
313dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
314dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (that->is_bitset()) {
315dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return (this->LubBitset() & that->as_bitset()) != 0;
316dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
317dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
318dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // (T1 \/ ... \/ Tn) overlaps T <=> (T1 overlaps T) \/ ... \/ (Tn overlaps T)
319dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (this->is_union()) {
320dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Unioned> unioned = this->as_union();
321dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
322dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<Type> this_i = union_get(unioned, i);
323dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (this_i->Maybe(that)) return true;
324dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
325dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return false;
326dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
327dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
328dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // T overlaps (T1 \/ ... \/ Tn) <=> (T overlaps T1) \/ ... \/ (T overlaps Tn)
329dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (that->is_union()) {
330dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Unioned> unioned = that->as_union();
331dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
332dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<Type> that_i = union_get(unioned, i);
333dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (this->Maybe(that_i)) return true;
334dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
335dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return false;
336dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
337dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
3381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(!that->is_union());
3391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (this->is_class()) {
3401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return that->is_class() && *this->as_class() == *that->as_class();
3411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
3421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (this->is_constant()) {
3431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return that->is_constant() && *this->as_constant() == *that->as_constant();
3441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
3451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
346dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return false;
347dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
348dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
349dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
350dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgbool Type::InUnion(Handle<Unioned> unioned, int current_size) {
351dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ASSERT(!this->is_union());
352dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  for (int i = 0; i < current_size; ++i) {
353dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Type> type = union_get(unioned, i);
3541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (this->Is(type)) return true;
355dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
356dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return false;
357dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
358dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
359e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
3601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Get non-bitsets from this which are not subsumed by union, store at unioned,
361dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// starting at index. Returns updated index.
362dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgint Type::ExtendUnion(Handle<Unioned> result, int current_size) {
363dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int old_size = current_size;
364dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (this->is_class() || this->is_constant()) {
365dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (!this->InUnion(result, old_size)) result->set(current_size++, this);
366dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else if (this->is_union()) {
367dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    Handle<Unioned> unioned = this->as_union();
368dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
369dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      Handle<Type> type = union_get(unioned, i);
370dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
371dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (type->is_bitset()) continue;
372dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      if (!type->InUnion(result, old_size)) result->set(current_size++, *type);
373dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    }
374dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
375dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return current_size;
376dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
377dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
378dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
379dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// Union is O(1) on simple bit unions, but O(n*m) on structured unions.
380dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org// TODO(rossberg): Should we use object sets somehow? Is it worth it?
381dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgType* Type::Union(Handle<Type> type1, Handle<Type> type2) {
382dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // Fast case: bit sets.
383dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (type1->is_bitset() && type2->is_bitset()) {
384dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return from_bitset(type1->as_bitset() | type2->as_bitset());
385dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
386dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
3871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Fast case: top or bottom types.
3881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type1->SameValue(Type::Any())) return *type1;
3891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type2->SameValue(Type::Any())) return *type2;
3901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type1->SameValue(Type::None())) return *type2;
3911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type2->SameValue(Type::None())) return *type1;
3921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
393dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // Semi-fast case: Unioned objects are neither involved nor produced.
394dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (!(type1->is_union() || type2->is_union())) {
395dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (type1->Is(type2)) return *type2;
396dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    if (type2->Is(type1)) return *type1;
397dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
398dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
399dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // Slow case: may need to produce a Unioned object.
400dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Isolate* isolate = NULL;
401dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int size = type1->is_bitset() || type2->is_bitset() ? 1 : 0;
402dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (!type1->is_bitset()) {
403ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    isolate = i::HeapObject::cast(*type1)->GetIsolate();
404dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    size += (type1->is_union() ? type1->as_union()->length() : 1);
405dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
406dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (!type2->is_bitset()) {
407ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    isolate = i::HeapObject::cast(*type2)->GetIsolate();
408dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    size += (type2->is_union() ? type2->as_union()->length() : 1);
409dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
410dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ASSERT(isolate != NULL);
411dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  ASSERT(size >= 2);
412dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
413dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  size = 0;
414dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
415dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  int bitset = type1->GlbBitset() | type2->GlbBitset();
416dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
417dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  size = type1->ExtendUnion(unioned, size);
418dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  size = type2->ExtendUnion(unioned, size);
419dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
420dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  if (size == 1) {
421dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return *union_get(unioned, 0);
422dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  } else if (size == unioned->length()) {
423dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org    return from_handle(unioned);
424dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  }
425dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
426dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  // There was an overlap. Copy to smaller union.
427dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
428dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
429dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return from_handle(result);
430dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
431dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
432dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
4331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Get non-bitsets from this which are also in that, store at unioned,
4341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// starting at index. Returns updated index.
4351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgint Type::ExtendIntersection(
4361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Unioned> result, Handle<Type> that, int current_size) {
4371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int old_size = current_size;
4381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (this->is_class() || this->is_constant()) {
4391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (this->Is(that) && !this->InUnion(result, old_size))
4401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      result->set(current_size++, this);
4411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (this->is_union()) {
4421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    Handle<Unioned> unioned = this->as_union();
4431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
4441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      Handle<Type> type = union_get(unioned, i);
4451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      ASSERT(i == 0 || !(type->is_bitset() || type->Is(union_get(unioned, 0))));
4461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (type->is_bitset()) continue;
4471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      if (type->Is(that) && !type->InUnion(result, old_size))
4481510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org        result->set(current_size++, *type);
4491510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    }
4501510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4511510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return current_size;
4521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
4531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4541510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4551510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// Intersection is O(1) on simple bit unions, but O(n*m) on structured unions.
4561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org// TODO(rossberg): Should we use object sets somehow? Is it worth it?
4571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgType* Type::Intersect(Handle<Type> type1, Handle<Type> type2) {
4581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Fast case: bit sets.
4591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type1->is_bitset() && type2->is_bitset()) {
4601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return from_bitset(type1->as_bitset() & type2->as_bitset());
4611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Fast case: top or bottom types.
4641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type1->SameValue(Type::None())) return *type1;
4651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type2->SameValue(Type::None())) return *type2;
4661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type1->SameValue(Type::Any())) return *type2;
4671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (type2->SameValue(Type::Any())) return *type1;
4681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Semi-fast case: Unioned objects are neither involved nor produced.
4701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!(type1->is_union() || type2->is_union())) {
4711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (type1->Is(type2)) return *type1;
4721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    if (type2->Is(type1)) return *type2;
4731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Slow case: may need to produce a Unioned object.
4761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Isolate* isolate = NULL;
4771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int size = 0;
4781510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!type1->is_bitset()) {
479ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    isolate = i::HeapObject::cast(*type1)->GetIsolate();
4801510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    size = (type1->is_union() ? type1->as_union()->length() : 2);
4811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (!type2->is_bitset()) {
483ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org    isolate = i::HeapObject::cast(*type2)->GetIsolate();
4841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    int size2 = (type2->is_union() ? type2->as_union()->length() : 2);
4851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    size = (size == 0 ? size2 : Min(size, size2));
4861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
4871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(isolate != NULL);
4881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ASSERT(size >= 2);
4891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<Unioned> unioned = isolate->factory()->NewFixedArray(size);
4901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size = 0;
4911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  int bitset = type1->GlbBitset() & type2->GlbBitset();
4931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (bitset != kNone) unioned->set(size++, from_bitset(bitset));
4941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size = type1->ExtendIntersection(unioned, type2, size);
4951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  size = type2->ExtendIntersection(unioned, type1, size);
4961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
4971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  if (size == 0) {
4981510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return None();
4991510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (size == 1) {
5001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return *union_get(unioned, 0);
5011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  } else if (size == unioned->length()) {
5021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    return from_handle(unioned);
5031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  }
5041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
5051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // There were dropped cases. Copy to smaller union.
5061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<Unioned> result = isolate->factory()->NewFixedArray(size);
5071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  for (int i = 0; i < size; ++i) result->set(i, unioned->get(i));
5081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  return from_handle(result);
5091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org}
5101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
5111510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org
512dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.orgType* Type::Optional(Handle<Type> type) {
513dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  return type->is_bitset()
514dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      ? from_bitset(type->as_bitset() | kUndefined)
515dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      : Union(type, Undefined()->handle_via_isolate_of(*type));
516dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org}
517dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org
518e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
519e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgRepresentation Representation::FromType(Handle<Type> type) {
520e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (type->Is(Type::None())) return Representation::None();
521fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (type->Is(Type::Smi())) return Representation::Smi();
522e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (type->Is(Type::Signed32())) return Representation::Integer32();
523e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  if (type->Is(Type::Number())) return Representation::Double();
524e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org  return Representation::Tagged();
525e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org}
526e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
527e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
528bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org#ifdef OBJECT_PRINT
529bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgvoid Type::TypePrint() {
530bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  TypePrint(stdout);
531bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  PrintF(stdout, "\n");
532bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  Flush(stdout);
533bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
534bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
535bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
536f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgconst char* Type::bitset_name(int bitset) {
537f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  switch (bitset) {
538f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    #define PRINT_COMPOSED_TYPE(type, value) case k##type: return #type;
539f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    BITSET_TYPE_LIST(PRINT_COMPOSED_TYPE)
540f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    #undef PRINT_COMPOSED_TYPE
541f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    default:
542f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      return NULL;
543f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  }
544f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
545f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
546f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
547bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgvoid Type::TypePrint(FILE* out) {
548bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (is_bitset()) {
549f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    int bitset = as_bitset();
550f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    const char* name = bitset_name(bitset);
551f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if (name != NULL) {
552f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      PrintF(out, "%s", name);
553f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    } else {
554f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      bool is_first = true;
555f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      PrintF(out, "(");
556f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      for (int mask = 1; mask != 0; mask = mask << 1) {
557f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        if ((bitset & mask) != 0) {
558f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org          if (!is_first) PrintF(out, " | ");
559f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org          is_first = false;
560f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org          PrintF(out, "%s", bitset_name(mask));
561f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org        }
562bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      }
563f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      PrintF(out, ")");
564bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    }
565bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else if (is_constant()) {
566a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    PrintF(out, "Constant(%p : ", static_cast<void*>(*as_constant()));
567a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    from_bitset(LubBitset())->TypePrint(out);
568a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    PrintF(")");
569bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else if (is_class()) {
570a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    PrintF(out, "Class(%p < ", static_cast<void*>(*as_class()));
571a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    from_bitset(LubBitset())->TypePrint(out);
572a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org    PrintF(")");
573bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  } else if (is_union()) {
574f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    PrintF(out, "(");
575bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    Handle<Unioned> unioned = as_union();
576bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    for (int i = 0; i < unioned->length(); ++i) {
577bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      Handle<Type> type_i = union_get(unioned, i);
578f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      if (i > 0) PrintF(out, " | ");
579bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org      type_i->TypePrint(out);
580bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    }
581f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    PrintF(out, ")");
582bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
583bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
584bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org#endif
585bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
586bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
587dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org} }  // namespace v8::internal
588