| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/v8.h" | 5 #include "src/v8.h" | 
| 6 | 6 | 
| 7 #include "src/interface.h" | 7 #include "src/interface.h" | 
| 8 | 8 | 
| 9 namespace v8 { | 9 namespace v8 { | 
| 10 namespace internal { | 10 namespace internal { | 
| 11 | 11 | 
|  | 12 // --------------------------------------------------------------------------- | 
|  | 13 // Initialization. | 
|  | 14 | 
|  | 15 struct Interface::ValueCreate { | 
|  | 16   static void Construct(Interface** ptr) { | 
|  | 17     *ptr = ::new Interface(VALUE + FROZEN); | 
|  | 18   } | 
|  | 19 }; | 
|  | 20 | 
|  | 21 struct Interface::ConstCreate { | 
|  | 22   static void Construct(Interface** ptr) { | 
|  | 23     *ptr = ::new Interface(VALUE + CONST + FROZEN); | 
|  | 24   } | 
|  | 25 }; | 
|  | 26 | 
|  | 27 base::LazyInstance<Interface*, Interface::ValueCreate>::type | 
|  | 28     Interface::value_interface_ = LAZY_INSTANCE_INITIALIZER; | 
|  | 29 | 
|  | 30 base::LazyInstance<Interface*, Interface::ConstCreate>::type | 
|  | 31     Interface::const_interface_ = LAZY_INSTANCE_INITIALIZER; | 
|  | 32 | 
|  | 33 | 
|  | 34 Interface* Interface::NewValue() { | 
|  | 35   return value_interface_.Get();  // Cached. | 
|  | 36 } | 
|  | 37 | 
|  | 38 Interface* Interface::NewConst() { | 
|  | 39   return const_interface_.Get();  // Cached. | 
|  | 40 } | 
|  | 41 | 
|  | 42 | 
|  | 43 // --------------------------------------------------------------------------- | 
|  | 44 // Lookup. | 
|  | 45 | 
| 12 Interface* Interface::Lookup(Handle<String> name, Zone* zone) { | 46 Interface* Interface::Lookup(Handle<String> name, Zone* zone) { | 
| 13   DCHECK(IsModule()); | 47   DCHECK(IsModule()); | 
| 14   ZoneHashMap* map = Chase()->exports_; | 48   ZoneHashMap* map = Chase()->exports_; | 
| 15   if (map == NULL) return NULL; | 49   if (map == nullptr) return nullptr; | 
| 16   ZoneAllocationPolicy allocator(zone); | 50   ZoneAllocationPolicy allocator(zone); | 
| 17   ZoneHashMap::Entry* p = map->Lookup(name.location(), name->Hash(), false, | 51   ZoneHashMap::Entry* p = | 
| 18                                       allocator); | 52       map->Lookup(name.location(), name->Hash(), false, allocator); | 
| 19   if (p == NULL) return NULL; | 53   if (p == nullptr) return nullptr; | 
| 20   DCHECK(*static_cast<String**>(p->key) == *name); | 54   DCHECK(*static_cast<String**>(p->key) == *name); | 
| 21   DCHECK(p->value != NULL); | 55   DCHECK(p->value != nullptr); | 
| 22   return static_cast<Interface*>(p->value); | 56   return static_cast<Interface*>(p->value); | 
| 23 } | 57 } | 
| 24 | 58 | 
| 25 | 59 | 
|  | 60 // --------------------------------------------------------------------------- | 
|  | 61 // Addition. | 
|  | 62 | 
| 26 #ifdef DEBUG | 63 #ifdef DEBUG | 
| 27 // Current nesting depth for debug output. | 64 // Current nesting depth for debug output. | 
| 28 class Nesting { | 65 class Nesting { | 
| 29  public: | 66  public: | 
| 30   Nesting()  { current_ += 2; } | 67   Nesting()  { current_ += 2; } | 
| 31   ~Nesting() { current_ -= 2; } | 68   ~Nesting() { current_ -= 2; } | 
| 32   static int current() { return current_; } | 69   static int current() { return current_; } | 
| 33  private: | 70  private: | 
| 34   static int current_; | 71   static int current_; | 
| 35 }; | 72 }; | 
| 36 | 73 | 
| 37 int Nesting::current_ = 0; | 74 int Nesting::current_ = 0; | 
| 38 #endif | 75 #endif | 
| 39 | 76 | 
| 40 | 77 | 
| 41 void Interface::DoAdd(const void* name, uint32_t hash, Interface* interface, | 78 void Interface::DoAdd(const void* name, uint32_t hash, Interface* interface, | 
| 42                       Zone* zone, bool* ok) { | 79                       Zone* zone, bool* ok) { | 
| 43   MakeModule(ok); | 80   MakeModule(ok); | 
| 44   if (!*ok) return; | 81   if (!*ok) return; | 
| 45 | 82 | 
| 46 #ifdef DEBUG | 83 #ifdef DEBUG | 
| 47   if (FLAG_print_interface_details) { | 84   if (FLAG_print_interface_details) { | 
| 48     PrintF("%*s# Adding...\n", Nesting::current(), ""); | 85     PrintF("%*s# Adding...\n", Nesting::current(), ""); | 
| 49     PrintF("%*sthis = ", Nesting::current(), ""); | 86     PrintF("%*sthis = ", Nesting::current(), ""); | 
| 50     this->Print(Nesting::current()); | 87     this->Print(Nesting::current()); | 
| 51     const AstRawString* symbol = static_cast<const AstRawString*>(name); | 88     const AstRawString* raw = static_cast<const AstRawString*>(name); | 
| 52     PrintF("%*s%.*s : ", Nesting::current(), "", symbol->length(), | 89     PrintF("%*s%.*s : ", Nesting::current(), "", | 
| 53            symbol->raw_data()); | 90            raw->length(), raw->raw_data()); | 
| 54     interface->Print(Nesting::current()); | 91     interface->Print(Nesting::current()); | 
| 55   } | 92   } | 
| 56 #endif | 93 #endif | 
| 57 | 94 | 
| 58   ZoneHashMap** map = &Chase()->exports_; | 95   ZoneHashMap** map = &Chase()->exports_; | 
| 59   ZoneAllocationPolicy allocator(zone); | 96   ZoneAllocationPolicy allocator(zone); | 
| 60 | 97 | 
| 61   if (*map == NULL) { | 98   if (*map == nullptr) { | 
| 62     *map = new(zone->New(sizeof(ZoneHashMap))) | 99     *map = new(zone->New(sizeof(ZoneHashMap))) | 
| 63         ZoneHashMap(ZoneHashMap::PointersMatch, | 100         ZoneHashMap(ZoneHashMap::PointersMatch, | 
| 64                     ZoneHashMap::kDefaultHashMapCapacity, allocator); | 101                     ZoneHashMap::kDefaultHashMapCapacity, allocator); | 
| 65   } | 102   } | 
| 66 | 103 | 
| 67   ZoneHashMap::Entry* p = | 104   ZoneHashMap::Entry* p = | 
| 68       (*map)->Lookup(const_cast<void*>(name), hash, !IsFrozen(), allocator); | 105       (*map)->Lookup(const_cast<void*>(name), hash, !IsFrozen(), allocator); | 
| 69   if (p == NULL) { | 106   if (p == nullptr) { | 
| 70     // This didn't have name but was frozen already, that's an error. | 107     // This didn't have name but was frozen already, that's an error. | 
| 71     *ok = false; | 108     *ok = false; | 
| 72   } else if (p->value == NULL) { | 109   } else if (p->value == nullptr) { | 
| 73     p->value = interface; | 110     p->value = interface; | 
| 74   } else { | 111   } else { | 
| 75 #ifdef DEBUG | 112 #ifdef DEBUG | 
| 76     Nesting nested; | 113     Nesting nested; | 
| 77 #endif | 114 #endif | 
| 78     static_cast<Interface*>(p->value)->Unify(interface, zone, ok); | 115     static_cast<Interface*>(p->value)->Unify(interface, zone, ok); | 
| 79   } | 116   } | 
| 80 | 117 | 
| 81 #ifdef DEBUG | 118 #ifdef DEBUG | 
| 82   if (FLAG_print_interface_details) { | 119   if (FLAG_print_interface_details) { | 
| 83     PrintF("%*sthis' = ", Nesting::current(), ""); | 120     PrintF("%*sthis' = ", Nesting::current(), ""); | 
| 84     this->Print(Nesting::current()); | 121     this->Print(Nesting::current()); | 
| 85     PrintF("%*s# Added.\n", Nesting::current(), ""); | 122     PrintF("%*s# Added.\n", Nesting::current(), ""); | 
| 86   } | 123   } | 
| 87 #endif | 124 #endif | 
| 88 } | 125 } | 
| 89 | 126 | 
| 90 | 127 | 
|  | 128 // --------------------------------------------------------------------------- | 
|  | 129 // Unification. | 
|  | 130 | 
| 91 void Interface::Unify(Interface* that, Zone* zone, bool* ok) { | 131 void Interface::Unify(Interface* that, Zone* zone, bool* ok) { | 
| 92   if (this->forward_) return this->Chase()->Unify(that, zone, ok); | 132   if (this->forward_) return this->Chase()->Unify(that, zone, ok); | 
| 93   if (that->forward_) return this->Unify(that->Chase(), zone, ok); | 133   if (that->forward_) return this->Unify(that->Chase(), zone, ok); | 
| 94   DCHECK(this->forward_ == NULL); | 134   DCHECK(this->forward_ == nullptr); | 
| 95   DCHECK(that->forward_ == NULL); | 135   DCHECK(that->forward_ == nullptr); | 
| 96 | 136 | 
| 97   *ok = true; | 137   *ok = true; | 
| 98   if (this == that) return; | 138   if (this == that) return; | 
| 99   if (this->IsValue()) { | 139   if (this->IsValue()) { | 
| 100     that->MakeValue(ok); | 140     that->MakeValue(ok); | 
| 101     if (*ok && this->IsConst()) that->MakeConst(ok); | 141     if (*ok && this->IsConst()) that->MakeConst(ok); | 
| 102     return; | 142     return; | 
| 103   } | 143   } | 
| 104   if (that->IsValue()) { | 144   if (that->IsValue()) { | 
| 105     this->MakeValue(ok); | 145     this->MakeValue(ok); | 
| 106     if (*ok && that->IsConst()) this->MakeConst(ok); | 146     if (*ok && that->IsConst()) this->MakeConst(ok); | 
| 107     return; | 147     return; | 
| 108   } | 148   } | 
| 109 | 149 | 
| 110 #ifdef DEBUG | 150 #ifdef DEBUG | 
| 111   if (FLAG_print_interface_details) { | 151   if (FLAG_print_interface_details) { | 
| 112     PrintF("%*s# Unifying...\n", Nesting::current(), ""); | 152     PrintF("%*s# Unifying...\n", Nesting::current(), ""); | 
| 113     PrintF("%*sthis = ", Nesting::current(), ""); | 153     PrintF("%*sthis = ", Nesting::current(), ""); | 
| 114     this->Print(Nesting::current()); | 154     this->Print(Nesting::current()); | 
| 115     PrintF("%*sthat = ", Nesting::current(), ""); | 155     PrintF("%*sthat = ", Nesting::current(), ""); | 
| 116     that->Print(Nesting::current()); | 156     that->Print(Nesting::current()); | 
| 117   } | 157   } | 
| 118 #endif | 158 #endif | 
| 119 | 159 | 
| 120   // Merge the smaller interface into the larger, for performance. | 160   // Merge the smaller interface into the larger, for performance. | 
| 121   if (this->exports_ != NULL && (that->exports_ == NULL || | 161   if (this->exports_ != nullptr && (that->exports_ == nullptr || | 
| 122       this->exports_->occupancy() >= that->exports_->occupancy())) { | 162       this->exports_->occupancy() >= that->exports_->occupancy())) { | 
| 123     this->DoUnify(that, ok, zone); | 163     this->DoUnify(that, ok, zone); | 
| 124   } else { | 164   } else { | 
| 125     that->DoUnify(this, ok, zone); | 165     that->DoUnify(this, ok, zone); | 
| 126   } | 166   } | 
| 127 | 167 | 
| 128 #ifdef DEBUG | 168 #ifdef DEBUG | 
| 129   if (FLAG_print_interface_details) { | 169   if (FLAG_print_interface_details) { | 
| 130     PrintF("%*sthis' = ", Nesting::current(), ""); | 170     PrintF("%*sthis' = ", Nesting::current(), ""); | 
| 131     this->Print(Nesting::current()); | 171     this->Print(Nesting::current()); | 
| 132     PrintF("%*sthat' = ", Nesting::current(), ""); | 172     PrintF("%*sthat' = ", Nesting::current(), ""); | 
| 133     that->Print(Nesting::current()); | 173     that->Print(Nesting::current()); | 
| 134     PrintF("%*s# Unified.\n", Nesting::current(), ""); | 174     PrintF("%*s# Unified.\n", Nesting::current(), ""); | 
| 135   } | 175   } | 
| 136 #endif | 176 #endif | 
| 137 } | 177 } | 
| 138 | 178 | 
| 139 | 179 | 
| 140 void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) { | 180 void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) { | 
| 141   DCHECK(this->forward_ == NULL); | 181   DCHECK(this->forward_ == nullptr); | 
| 142   DCHECK(that->forward_ == NULL); | 182   DCHECK(that->forward_ == nullptr); | 
| 143   DCHECK(!this->IsValue()); | 183   DCHECK(!this->IsValue()); | 
| 144   DCHECK(!that->IsValue()); | 184   DCHECK(!that->IsValue()); | 
| 145   DCHECK(this->index_ == -1); | 185   DCHECK(this->index_ == -1); | 
| 146   DCHECK(that->index_ == -1); | 186   DCHECK(that->index_ == -1); | 
| 147   DCHECK(*ok); | 187   DCHECK(*ok); | 
| 148 | 188 | 
| 149 #ifdef DEBUG | 189 #ifdef DEBUG | 
| 150     Nesting nested; | 190     Nesting nested; | 
| 151 #endif | 191 #endif | 
| 152 | 192 | 
| 153   // Try to merge all members from that into this. | 193   // Try to merge all members from that into this. | 
| 154   ZoneHashMap* map = that->exports_; | 194   ZoneHashMap* map = that->exports_; | 
| 155   if (map != NULL) { | 195   if (map != nullptr) { | 
| 156     for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 196     for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { | 
| 157       this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok); | 197       this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok); | 
| 158       if (!*ok) return; | 198       if (!*ok) return; | 
| 159     } | 199     } | 
| 160   } | 200   } | 
| 161 | 201 | 
| 162   // If the new interface is larger than that's, then there were members in | 202   // If the new interface is larger than that's, then there were members in | 
| 163   // 'this' which 'that' didn't have. If 'that' was frozen that is an error. | 203   // 'this' which 'that' didn't have. If 'that' was frozen that is an error. | 
| 164   int this_size = this->exports_ == NULL ? 0 : this->exports_->occupancy(); | 204   int this_size = this->exports_ == nullptr ? 0 : this->exports_->occupancy(); | 
| 165   int that_size = map == NULL ? 0 : map->occupancy(); | 205   int that_size = map == nullptr ? 0 : map->occupancy(); | 
| 166   if (that->IsFrozen() && this_size > that_size) { | 206   if (that->IsFrozen() && this_size > that_size) { | 
| 167     *ok = false; | 207     *ok = false; | 
| 168     return; | 208     return; | 
| 169   } | 209   } | 
| 170 | 210 | 
| 171   // Merge interfaces. | 211   // Merge interfaces. | 
| 172   this->flags_ |= that->flags_; | 212   this->flags_ |= that->flags_; | 
| 173   that->forward_ = this; | 213   that->forward_ = this; | 
| 174 } | 214 } | 
| 175 | 215 | 
| 176 | 216 | 
|  | 217 // --------------------------------------------------------------------------- | 
|  | 218 // Printing. | 
|  | 219 | 
| 177 #ifdef DEBUG | 220 #ifdef DEBUG | 
| 178 void Interface::Print(int n) { | 221 void Interface::Print(int n) { | 
| 179   int n0 = n > 0 ? n : 0; | 222   int n0 = n > 0 ? n : 0; | 
| 180 | 223 | 
| 181   if (FLAG_print_interface_details) { | 224   if (FLAG_print_interface_details) { | 
| 182     PrintF("%p", static_cast<void*>(this)); | 225     PrintF("%p", static_cast<void*>(this)); | 
| 183     for (Interface* link = this->forward_; link != NULL; link = link->forward_) | 226     for (Interface* link = this->forward_; link != nullptr; | 
|  | 227         link = link->forward_) { | 
| 184       PrintF("->%p", static_cast<void*>(link)); | 228       PrintF("->%p", static_cast<void*>(link)); | 
|  | 229     } | 
| 185     PrintF(" "); | 230     PrintF(" "); | 
| 186   } | 231   } | 
| 187 | 232 | 
| 188   if (IsUnknown()) { | 233   if (IsUnknown()) { | 
| 189     PrintF("unknown\n"); | 234     PrintF("unknown\n"); | 
| 190   } else if (IsConst()) { | 235   } else if (IsConst()) { | 
| 191     PrintF("const\n"); | 236     PrintF("const\n"); | 
| 192   } else if (IsValue()) { | 237   } else if (IsValue()) { | 
| 193     PrintF("value\n"); | 238     PrintF("value\n"); | 
| 194   } else if (IsModule()) { | 239   } else if (IsModule()) { | 
| 195     PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) "); | 240     PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) "); | 
| 196     ZoneHashMap* map = Chase()->exports_; | 241     ZoneHashMap* map = Chase()->exports_; | 
| 197     if (map == NULL || map->occupancy() == 0) { | 242     if (map == nullptr || map->occupancy() == 0) { | 
| 198       PrintF("}\n"); | 243       PrintF("}\n"); | 
| 199     } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) { | 244     } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) { | 
| 200       // Avoid infinite recursion on cyclic types. | 245       // Avoid infinite recursion on cyclic types. | 
| 201       PrintF("...}\n"); | 246       PrintF("...}\n"); | 
| 202     } else { | 247     } else { | 
| 203       PrintF("\n"); | 248       PrintF("\n"); | 
| 204       for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) { | 249       for (ZoneHashMap::Entry* p = map->Start(); | 
|  | 250            p != nullptr; p = map->Next(p)) { | 
| 205         String* name = *static_cast<String**>(p->key); | 251         String* name = *static_cast<String**>(p->key); | 
| 206         Interface* interface = static_cast<Interface*>(p->value); | 252         Interface* interface = static_cast<Interface*>(p->value); | 
| 207         PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray()); | 253         PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray()); | 
| 208         interface->Print(n0 + 2); | 254         interface->Print(n0 + 2); | 
| 209       } | 255       } | 
| 210       PrintF("%*s}\n", n0, ""); | 256       PrintF("%*s}\n", n0, ""); | 
| 211     } | 257     } | 
| 212   } | 258   } | 
| 213 } | 259 } | 
| 214 #endif | 260 #endif | 
| 215 | 261 | 
| 216 } }  // namespace v8::internal | 262 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|