~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to deps/v8/src/interface.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
 
2
// Redistribution and use in source and binary forms, with or without
 
3
// modification, are permitted provided that the following conditions are
 
4
// met:
 
5
//
 
6
//     * Redistributions of source code must retain the above copyright
 
7
//       notice, this list of conditions and the following disclaimer.
 
8
//     * Redistributions in binary form must reproduce the above
 
9
//       copyright notice, this list of conditions and the following
 
10
//       disclaimer in the documentation and/or other materials provided
 
11
//       with the distribution.
 
12
//     * Neither the name of Google Inc. nor the names of its
 
13
//       contributors may be used to endorse or promote products derived
 
14
//       from this software without specific prior written permission.
 
15
//
 
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
#include "v8.h"
 
29
 
 
30
#include "interface.h"
 
31
 
 
32
namespace v8 {
 
33
namespace internal {
 
34
 
 
35
static bool Match(void* key1, void* key2) {
 
36
  String* name1 = *static_cast<String**>(key1);
 
37
  String* name2 = *static_cast<String**>(key2);
 
38
  ASSERT(name1->IsSymbol());
 
39
  ASSERT(name2->IsSymbol());
 
40
  return name1 == name2;
 
41
}
 
42
 
 
43
 
 
44
Interface* Interface::Lookup(Handle<String> name, Zone* zone) {
 
45
  ASSERT(IsModule());
 
46
  ZoneHashMap* map = Chase()->exports_;
 
47
  if (map == NULL) return NULL;
 
48
  ZoneAllocationPolicy allocator(zone);
 
49
  ZoneHashMap::Entry* p = map->Lookup(name.location(), name->Hash(), false,
 
50
                                      allocator);
 
51
  if (p == NULL) return NULL;
 
52
  ASSERT(*static_cast<String**>(p->key) == *name);
 
53
  ASSERT(p->value != NULL);
 
54
  return static_cast<Interface*>(p->value);
 
55
}
 
56
 
 
57
 
 
58
#ifdef DEBUG
 
59
// Current nesting depth for debug output.
 
60
class Nesting {
 
61
 public:
 
62
  Nesting()  { current_ += 2; }
 
63
  ~Nesting() { current_ -= 2; }
 
64
  static int current() { return current_; }
 
65
 private:
 
66
  static int current_;
 
67
};
 
68
 
 
69
int Nesting::current_ = 0;
 
70
#endif
 
71
 
 
72
 
 
73
void Interface::DoAdd(
 
74
    void* name, uint32_t hash, Interface* interface, Zone* zone, bool* ok) {
 
75
  MakeModule(ok);
 
76
  if (!*ok) return;
 
77
 
 
78
#ifdef DEBUG
 
79
  if (FLAG_print_interface_details) {
 
80
    PrintF("%*s# Adding...\n", Nesting::current(), "");
 
81
    PrintF("%*sthis = ", Nesting::current(), "");
 
82
    this->Print(Nesting::current());
 
83
    PrintF("%*s%s : ", Nesting::current(), "",
 
84
           (*static_cast<String**>(name))->ToAsciiArray());
 
85
    interface->Print(Nesting::current());
 
86
  }
 
87
#endif
 
88
 
 
89
  ZoneHashMap** map = &Chase()->exports_;
 
90
  ZoneAllocationPolicy allocator(zone);
 
91
 
 
92
  if (*map == NULL)
 
93
    *map = new ZoneHashMap(Match, ZoneHashMap::kDefaultHashMapCapacity,
 
94
                           allocator);
 
95
 
 
96
  ZoneHashMap::Entry* p = (*map)->Lookup(name, hash, !IsFrozen(), allocator);
 
97
  if (p == NULL) {
 
98
    // This didn't have name but was frozen already, that's an error.
 
99
    *ok = false;
 
100
  } else if (p->value == NULL) {
 
101
    p->value = interface;
 
102
  } else {
 
103
#ifdef DEBUG
 
104
    Nesting nested;
 
105
#endif
 
106
    static_cast<Interface*>(p->value)->Unify(interface, zone, ok);
 
107
  }
 
108
 
 
109
#ifdef DEBUG
 
110
  if (FLAG_print_interface_details) {
 
111
    PrintF("%*sthis' = ", Nesting::current(), "");
 
112
    this->Print(Nesting::current());
 
113
    PrintF("%*s# Added.\n", Nesting::current(), "");
 
114
  }
 
115
#endif
 
116
}
 
117
 
 
118
 
 
119
void Interface::Unify(Interface* that, Zone* zone, bool* ok) {
 
120
  if (this->forward_) return this->Chase()->Unify(that, zone, ok);
 
121
  if (that->forward_) return this->Unify(that->Chase(), zone, ok);
 
122
  ASSERT(this->forward_ == NULL);
 
123
  ASSERT(that->forward_ == NULL);
 
124
 
 
125
  *ok = true;
 
126
  if (this == that) return;
 
127
  if (this->IsValue()) {
 
128
    that->MakeValue(ok);
 
129
    if (*ok && this->IsConst()) that->MakeConst(ok);
 
130
    return;
 
131
  }
 
132
  if (that->IsValue()) {
 
133
    this->MakeValue(ok);
 
134
    if (*ok && that->IsConst()) this->MakeConst(ok);
 
135
    return;
 
136
  }
 
137
 
 
138
#ifdef DEBUG
 
139
  if (FLAG_print_interface_details) {
 
140
    PrintF("%*s# Unifying...\n", Nesting::current(), "");
 
141
    PrintF("%*sthis = ", Nesting::current(), "");
 
142
    this->Print(Nesting::current());
 
143
    PrintF("%*sthat = ", Nesting::current(), "");
 
144
    that->Print(Nesting::current());
 
145
  }
 
146
#endif
 
147
 
 
148
  // Merge the smaller interface into the larger, for performance.
 
149
  if (this->exports_ != NULL && (that->exports_ == NULL ||
 
150
      this->exports_->occupancy() >= that->exports_->occupancy())) {
 
151
    this->DoUnify(that, ok, zone);
 
152
  } else {
 
153
    that->DoUnify(this, ok, zone);
 
154
  }
 
155
 
 
156
#ifdef DEBUG
 
157
  if (FLAG_print_interface_details) {
 
158
    PrintF("%*sthis' = ", Nesting::current(), "");
 
159
    this->Print(Nesting::current());
 
160
    PrintF("%*sthat' = ", Nesting::current(), "");
 
161
    that->Print(Nesting::current());
 
162
    PrintF("%*s# Unified.\n", Nesting::current(), "");
 
163
  }
 
164
#endif
 
165
}
 
166
 
 
167
 
 
168
void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) {
 
169
  ASSERT(this->forward_ == NULL);
 
170
  ASSERT(that->forward_ == NULL);
 
171
  ASSERT(!this->IsValue());
 
172
  ASSERT(!that->IsValue());
 
173
  ASSERT(*ok);
 
174
 
 
175
#ifdef DEBUG
 
176
    Nesting nested;
 
177
#endif
 
178
 
 
179
  // Try to merge all members from that into this.
 
180
  ZoneHashMap* map = that->exports_;
 
181
  if (map != NULL) {
 
182
    for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
 
183
      this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok);
 
184
      if (!*ok) return;
 
185
    }
 
186
  }
 
187
 
 
188
  // If the new interface is larger than that's, then there were members in
 
189
  // 'this' which 'that' didn't have. If 'that' was frozen that is an error.
 
190
  int this_size = this->exports_ == NULL ? 0 : this->exports_->occupancy();
 
191
  int that_size = map == NULL ? 0 : map->occupancy();
 
192
  if (that->IsFrozen() && this_size > that_size) {
 
193
    *ok = false;
 
194
    return;
 
195
  }
 
196
 
 
197
  // Merge instance.
 
198
  if (!that->instance_.is_null()) {
 
199
    if (!this->instance_.is_null() && *this->instance_ != *that->instance_) {
 
200
      *ok = false;
 
201
      return;
 
202
    }
 
203
    this->instance_ = that->instance_;
 
204
  }
 
205
 
 
206
  // Merge interfaces.
 
207
  this->flags_ |= that->flags_;
 
208
  that->forward_ = this;
 
209
}
 
210
 
 
211
 
 
212
#ifdef DEBUG
 
213
void Interface::Print(int n) {
 
214
  int n0 = n > 0 ? n : 0;
 
215
 
 
216
  if (FLAG_print_interface_details) {
 
217
    PrintF("%p", static_cast<void*>(this));
 
218
    for (Interface* link = this->forward_; link != NULL; link = link->forward_)
 
219
      PrintF("->%p", static_cast<void*>(link));
 
220
    PrintF(" ");
 
221
  }
 
222
 
 
223
  if (IsUnknown()) {
 
224
    PrintF("unknown\n");
 
225
  } else if (IsConst()) {
 
226
    PrintF("const\n");
 
227
  } else if (IsValue()) {
 
228
    PrintF("value\n");
 
229
  } else if (IsModule()) {
 
230
    PrintF("module %s{", IsFrozen() ? "" : "(unresolved) ");
 
231
    ZoneHashMap* map = Chase()->exports_;
 
232
    if (map == NULL || map->occupancy() == 0) {
 
233
      PrintF("}\n");
 
234
    } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
 
235
      // Avoid infinite recursion on cyclic types.
 
236
      PrintF("...}\n");
 
237
    } else {
 
238
      PrintF("\n");
 
239
      for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
 
240
        String* name = *static_cast<String**>(p->key);
 
241
        Interface* interface = static_cast<Interface*>(p->value);
 
242
        PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
 
243
        interface->Print(n0 + 2);
 
244
      }
 
245
      PrintF("%*s}\n", n0, "");
 
246
    }
 
247
  }
 
248
}
 
249
#endif
 
250
 
 
251
} }  // namespace v8::internal