~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/scopeinfo.cc

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2011 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 <stdlib.h>
 
29
 
 
30
#include "v8.h"
 
31
 
 
32
#include "scopeinfo.h"
 
33
#include "scopes.h"
 
34
 
 
35
#include "allocation-inl.h"
 
36
 
 
37
namespace v8 {
 
38
namespace internal {
 
39
 
 
40
 
 
41
Handle<ScopeInfo> ScopeInfo::Create(Scope* scope, Zone* zone) {
 
42
  // Collect stack and context locals.
 
43
  ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone);
 
44
  ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone);
 
45
  scope->CollectStackAndContextLocals(&stack_locals, &context_locals);
 
46
  const int stack_local_count = stack_locals.length();
 
47
  const int context_local_count = context_locals.length();
 
48
  // Make sure we allocate the correct amount.
 
49
  ASSERT(scope->StackLocalCount() == stack_local_count);
 
50
  ASSERT(scope->ContextLocalCount() == context_local_count);
 
51
 
 
52
  // Determine use and location of the function variable if it is present.
 
53
  FunctionVariableInfo function_name_info;
 
54
  VariableMode function_variable_mode;
 
55
  if (scope->is_function_scope() && scope->function() != NULL) {
 
56
    Variable* var = scope->function()->proxy()->var();
 
57
    if (!var->is_used()) {
 
58
      function_name_info = UNUSED;
 
59
    } else if (var->IsContextSlot()) {
 
60
      function_name_info = CONTEXT;
 
61
    } else {
 
62
      ASSERT(var->IsStackLocal());
 
63
      function_name_info = STACK;
 
64
    }
 
65
    function_variable_mode = var->mode();
 
66
  } else {
 
67
    function_name_info = NONE;
 
68
    function_variable_mode = VAR;
 
69
  }
 
70
 
 
71
  const bool has_function_name = function_name_info != NONE;
 
72
  const int parameter_count = scope->num_parameters();
 
73
  const int length = kVariablePartIndex
 
74
      + parameter_count + stack_local_count + 2 * context_local_count
 
75
      + (has_function_name ? 2 : 0);
 
76
 
 
77
  Handle<ScopeInfo> scope_info = FACTORY->NewScopeInfo(length);
 
78
 
 
79
  // Encode the flags.
 
80
  int flags = TypeField::encode(scope->type()) |
 
81
      CallsEvalField::encode(scope->calls_eval()) |
 
82
      LanguageModeField::encode(scope->language_mode()) |
 
83
      FunctionVariableField::encode(function_name_info) |
 
84
      FunctionVariableMode::encode(function_variable_mode);
 
85
  scope_info->SetFlags(flags);
 
86
  scope_info->SetParameterCount(parameter_count);
 
87
  scope_info->SetStackLocalCount(stack_local_count);
 
88
  scope_info->SetContextLocalCount(context_local_count);
 
89
 
 
90
  int index = kVariablePartIndex;
 
91
  // Add parameters.
 
92
  ASSERT(index == scope_info->ParameterEntriesIndex());
 
93
  for (int i = 0; i < parameter_count; ++i) {
 
94
    scope_info->set(index++, *scope->parameter(i)->name());
 
95
  }
 
96
 
 
97
  // Add stack locals' names. We are assuming that the stack locals'
 
98
  // slots are allocated in increasing order, so we can simply add
 
99
  // them to the ScopeInfo object.
 
100
  ASSERT(index == scope_info->StackLocalEntriesIndex());
 
101
  for (int i = 0; i < stack_local_count; ++i) {
 
102
    ASSERT(stack_locals[i]->index() == i);
 
103
    scope_info->set(index++, *stack_locals[i]->name());
 
104
  }
 
105
 
 
106
  // Due to usage analysis, context-allocated locals are not necessarily in
 
107
  // increasing order: Some of them may be parameters which are allocated before
 
108
  // the non-parameter locals. When the non-parameter locals are sorted
 
109
  // according to usage, the allocated slot indices may not be in increasing
 
110
  // order with the variable list anymore. Thus, we first need to sort them by
 
111
  // context slot index before adding them to the ScopeInfo object.
 
112
  context_locals.Sort(&Variable::CompareIndex);
 
113
 
 
114
  // Add context locals' names.
 
115
  ASSERT(index == scope_info->ContextLocalNameEntriesIndex());
 
116
  for (int i = 0; i < context_local_count; ++i) {
 
117
    scope_info->set(index++, *context_locals[i]->name());
 
118
  }
 
119
 
 
120
  // Add context locals' info.
 
121
  ASSERT(index == scope_info->ContextLocalInfoEntriesIndex());
 
122
  for (int i = 0; i < context_local_count; ++i) {
 
123
    Variable* var = context_locals[i];
 
124
    uint32_t value = ContextLocalMode::encode(var->mode()) |
 
125
        ContextLocalInitFlag::encode(var->initialization_flag());
 
126
    scope_info->set(index++, Smi::FromInt(value));
 
127
  }
 
128
 
 
129
  // If present, add the function variable name and its index.
 
130
  ASSERT(index == scope_info->FunctionNameEntryIndex());
 
131
  if (has_function_name) {
 
132
    int var_index = scope->function()->proxy()->var()->index();
 
133
    scope_info->set(index++, *scope->function()->proxy()->name());
 
134
    scope_info->set(index++, Smi::FromInt(var_index));
 
135
    ASSERT(function_name_info != STACK ||
 
136
           (var_index == scope_info->StackLocalCount() &&
 
137
            var_index == scope_info->StackSlotCount() - 1));
 
138
    ASSERT(function_name_info != CONTEXT ||
 
139
           var_index == scope_info->ContextLength() - 1);
 
140
  }
 
141
 
 
142
  ASSERT(index == scope_info->length());
 
143
  ASSERT(scope->num_parameters() == scope_info->ParameterCount());
 
144
  ASSERT(scope->num_stack_slots() == scope_info->StackSlotCount());
 
145
  ASSERT(scope->num_heap_slots() == scope_info->ContextLength() ||
 
146
         (scope->num_heap_slots() == kVariablePartIndex &&
 
147
          scope_info->ContextLength() == 0));
 
148
  return scope_info;
 
149
}
 
150
 
 
151
 
 
152
ScopeInfo* ScopeInfo::Empty() {
 
153
  return reinterpret_cast<ScopeInfo*>(HEAP->empty_fixed_array());
 
154
}
 
155
 
 
156
 
 
157
ScopeType ScopeInfo::Type() {
 
158
  ASSERT(length() > 0);
 
159
  return TypeField::decode(Flags());
 
160
}
 
161
 
 
162
 
 
163
bool ScopeInfo::CallsEval() {
 
164
  return length() > 0 && CallsEvalField::decode(Flags());
 
165
}
 
166
 
 
167
 
 
168
LanguageMode ScopeInfo::language_mode() {
 
169
  return length() > 0 ? LanguageModeField::decode(Flags()) : CLASSIC_MODE;
 
170
}
 
171
 
 
172
 
 
173
int ScopeInfo::LocalCount() {
 
174
  return StackLocalCount() + ContextLocalCount();
 
175
}
 
176
 
 
177
 
 
178
int ScopeInfo::StackSlotCount() {
 
179
  if (length() > 0) {
 
180
    bool function_name_stack_slot =
 
181
        FunctionVariableField::decode(Flags()) == STACK;
 
182
    return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
 
183
  }
 
184
  return 0;
 
185
}
 
186
 
 
187
 
 
188
int ScopeInfo::ContextLength() {
 
189
  if (length() > 0) {
 
190
    int context_locals = ContextLocalCount();
 
191
    bool function_name_context_slot =
 
192
        FunctionVariableField::decode(Flags()) == CONTEXT;
 
193
    bool has_context = context_locals > 0 ||
 
194
        function_name_context_slot ||
 
195
        Type() == WITH_SCOPE ||
 
196
        (Type() == FUNCTION_SCOPE && CallsEval()) ||
 
197
        Type() == MODULE_SCOPE;
 
198
    if (has_context) {
 
199
      return Context::MIN_CONTEXT_SLOTS + context_locals +
 
200
          (function_name_context_slot ? 1 : 0);
 
201
    }
 
202
  }
 
203
  return 0;
 
204
}
 
205
 
 
206
 
 
207
bool ScopeInfo::HasFunctionName() {
 
208
  if (length() > 0) {
 
209
    return NONE != FunctionVariableField::decode(Flags());
 
210
  } else {
 
211
    return false;
 
212
  }
 
213
}
 
214
 
 
215
 
 
216
bool ScopeInfo::HasHeapAllocatedLocals() {
 
217
  if (length() > 0) {
 
218
    return ContextLocalCount() > 0;
 
219
  } else {
 
220
    return false;
 
221
  }
 
222
}
 
223
 
 
224
 
 
225
bool ScopeInfo::HasContext() {
 
226
  return ContextLength() > 0;
 
227
}
 
228
 
 
229
 
 
230
String* ScopeInfo::FunctionName() {
 
231
  ASSERT(HasFunctionName());
 
232
  return String::cast(get(FunctionNameEntryIndex()));
 
233
}
 
234
 
 
235
 
 
236
String* ScopeInfo::ParameterName(int var) {
 
237
  ASSERT(0 <= var && var < ParameterCount());
 
238
  int info_index = ParameterEntriesIndex() + var;
 
239
  return String::cast(get(info_index));
 
240
}
 
241
 
 
242
 
 
243
String* ScopeInfo::LocalName(int var) {
 
244
  ASSERT(0 <= var && var < LocalCount());
 
245
  ASSERT(StackLocalEntriesIndex() + StackLocalCount() ==
 
246
         ContextLocalNameEntriesIndex());
 
247
  int info_index = StackLocalEntriesIndex() + var;
 
248
  return String::cast(get(info_index));
 
249
}
 
250
 
 
251
 
 
252
String* ScopeInfo::StackLocalName(int var) {
 
253
  ASSERT(0 <= var && var < StackLocalCount());
 
254
  int info_index = StackLocalEntriesIndex() + var;
 
255
  return String::cast(get(info_index));
 
256
}
 
257
 
 
258
 
 
259
String* ScopeInfo::ContextLocalName(int var) {
 
260
  ASSERT(0 <= var && var < ContextLocalCount());
 
261
  int info_index = ContextLocalNameEntriesIndex() + var;
 
262
  return String::cast(get(info_index));
 
263
}
 
264
 
 
265
 
 
266
VariableMode ScopeInfo::ContextLocalMode(int var) {
 
267
  ASSERT(0 <= var && var < ContextLocalCount());
 
268
  int info_index = ContextLocalInfoEntriesIndex() + var;
 
269
  int value = Smi::cast(get(info_index))->value();
 
270
  return ContextLocalMode::decode(value);
 
271
}
 
272
 
 
273
 
 
274
InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
 
275
  ASSERT(0 <= var && var < ContextLocalCount());
 
276
  int info_index = ContextLocalInfoEntriesIndex() + var;
 
277
  int value = Smi::cast(get(info_index))->value();
 
278
  return ContextLocalInitFlag::decode(value);
 
279
}
 
280
 
 
281
 
 
282
int ScopeInfo::StackSlotIndex(String* name) {
 
283
  ASSERT(name->IsSymbol());
 
284
  if (length() > 0) {
 
285
    int start = StackLocalEntriesIndex();
 
286
    int end = StackLocalEntriesIndex() + StackLocalCount();
 
287
    for (int i = start; i < end; ++i) {
 
288
      if (name == get(i)) {
 
289
        return i - start;
 
290
      }
 
291
    }
 
292
  }
 
293
  return -1;
 
294
}
 
295
 
 
296
 
 
297
int ScopeInfo::ContextSlotIndex(String* name,
 
298
                                VariableMode* mode,
 
299
                                InitializationFlag* init_flag) {
 
300
  ASSERT(name->IsSymbol());
 
301
  ASSERT(mode != NULL);
 
302
  ASSERT(init_flag != NULL);
 
303
  if (length() > 0) {
 
304
    ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache();
 
305
    int result = context_slot_cache->Lookup(this, name, mode, init_flag);
 
306
    if (result != ContextSlotCache::kNotFound) {
 
307
      ASSERT(result < ContextLength());
 
308
      return result;
 
309
    }
 
310
 
 
311
    int start = ContextLocalNameEntriesIndex();
 
312
    int end = ContextLocalNameEntriesIndex() + ContextLocalCount();
 
313
    for (int i = start; i < end; ++i) {
 
314
      if (name == get(i)) {
 
315
        int var = i - start;
 
316
        *mode = ContextLocalMode(var);
 
317
        *init_flag = ContextLocalInitFlag(var);
 
318
        result = Context::MIN_CONTEXT_SLOTS + var;
 
319
        context_slot_cache->Update(this, name, *mode, *init_flag, result);
 
320
        ASSERT(result < ContextLength());
 
321
        return result;
 
322
      }
 
323
    }
 
324
    context_slot_cache->Update(this, name, INTERNAL, kNeedsInitialization, -1);
 
325
  }
 
326
  return -1;
 
327
}
 
328
 
 
329
 
 
330
int ScopeInfo::ParameterIndex(String* name) {
 
331
  ASSERT(name->IsSymbol());
 
332
  if (length() > 0) {
 
333
    // We must read parameters from the end since for
 
334
    // multiply declared parameters the value of the
 
335
    // last declaration of that parameter is used
 
336
    // inside a function (and thus we need to look
 
337
    // at the last index). Was bug# 1110337.
 
338
    int start = ParameterEntriesIndex();
 
339
    int end = ParameterEntriesIndex() + ParameterCount();
 
340
    for (int i = end - 1; i >= start; --i) {
 
341
      if (name == get(i)) {
 
342
        return i - start;
 
343
      }
 
344
    }
 
345
  }
 
346
  return -1;
 
347
}
 
348
 
 
349
 
 
350
int ScopeInfo::FunctionContextSlotIndex(String* name, VariableMode* mode) {
 
351
  ASSERT(name->IsSymbol());
 
352
  ASSERT(mode != NULL);
 
353
  if (length() > 0) {
 
354
    if (FunctionVariableField::decode(Flags()) == CONTEXT &&
 
355
        FunctionName() == name) {
 
356
      *mode = FunctionVariableMode::decode(Flags());
 
357
      return Smi::cast(get(FunctionNameEntryIndex() + 1))->value();
 
358
    }
 
359
  }
 
360
  return -1;
 
361
}
 
362
 
 
363
 
 
364
int ScopeInfo::ParameterEntriesIndex() {
 
365
  ASSERT(length() > 0);
 
366
  return kVariablePartIndex;
 
367
}
 
368
 
 
369
 
 
370
int ScopeInfo::StackLocalEntriesIndex() {
 
371
  return ParameterEntriesIndex() + ParameterCount();
 
372
}
 
373
 
 
374
 
 
375
int ScopeInfo::ContextLocalNameEntriesIndex() {
 
376
  return StackLocalEntriesIndex() + StackLocalCount();
 
377
}
 
378
 
 
379
 
 
380
int ScopeInfo::ContextLocalInfoEntriesIndex() {
 
381
  return ContextLocalNameEntriesIndex() + ContextLocalCount();
 
382
}
 
383
 
 
384
 
 
385
int ScopeInfo::FunctionNameEntryIndex() {
 
386
  return ContextLocalInfoEntriesIndex() + ContextLocalCount();
 
387
}
 
388
 
 
389
 
 
390
int ContextSlotCache::Hash(Object* data, String* name) {
 
391
  // Uses only lower 32 bits if pointers are larger.
 
392
  uintptr_t addr_hash =
 
393
      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
 
394
  return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
 
395
}
 
396
 
 
397
 
 
398
int ContextSlotCache::Lookup(Object* data,
 
399
                             String* name,
 
400
                             VariableMode* mode,
 
401
                             InitializationFlag* init_flag) {
 
402
  int index = Hash(data, name);
 
403
  Key& key = keys_[index];
 
404
  if ((key.data == data) && key.name->Equals(name)) {
 
405
    Value result(values_[index]);
 
406
    if (mode != NULL) *mode = result.mode();
 
407
    if (init_flag != NULL) *init_flag = result.initialization_flag();
 
408
    return result.index() + kNotFound;
 
409
  }
 
410
  return kNotFound;
 
411
}
 
412
 
 
413
 
 
414
void ContextSlotCache::Update(Object* data,
 
415
                              String* name,
 
416
                              VariableMode mode,
 
417
                              InitializationFlag init_flag,
 
418
                              int slot_index) {
 
419
  String* symbol;
 
420
  ASSERT(slot_index > kNotFound);
 
421
  if (HEAP->LookupSymbolIfExists(name, &symbol)) {
 
422
    int index = Hash(data, symbol);
 
423
    Key& key = keys_[index];
 
424
    key.data = data;
 
425
    key.name = symbol;
 
426
    // Please note value only takes a uint as index.
 
427
    values_[index] = Value(mode, init_flag, slot_index - kNotFound).raw();
 
428
#ifdef DEBUG
 
429
    ValidateEntry(data, name, mode, init_flag, slot_index);
 
430
#endif
 
431
  }
 
432
}
 
433
 
 
434
 
 
435
void ContextSlotCache::Clear() {
 
436
  for (int index = 0; index < kLength; index++) keys_[index].data = NULL;
 
437
}
 
438
 
 
439
 
 
440
#ifdef DEBUG
 
441
 
 
442
void ContextSlotCache::ValidateEntry(Object* data,
 
443
                                     String* name,
 
444
                                     VariableMode mode,
 
445
                                     InitializationFlag init_flag,
 
446
                                     int slot_index) {
 
447
  String* symbol;
 
448
  if (HEAP->LookupSymbolIfExists(name, &symbol)) {
 
449
    int index = Hash(data, name);
 
450
    Key& key = keys_[index];
 
451
    ASSERT(key.data == data);
 
452
    ASSERT(key.name->Equals(name));
 
453
    Value result(values_[index]);
 
454
    ASSERT(result.mode() == mode);
 
455
    ASSERT(result.initialization_flag() == init_flag);
 
456
    ASSERT(result.index() + kNotFound == slot_index);
 
457
  }
 
458
}
 
459
 
 
460
 
 
461
static void PrintList(const char* list_name,
 
462
                      int nof_internal_slots,
 
463
                      int start,
 
464
                      int end,
 
465
                      ScopeInfo* scope_info) {
 
466
  if (start < end) {
 
467
    PrintF("\n  // %s\n", list_name);
 
468
    if (nof_internal_slots > 0) {
 
469
      PrintF("  %2d - %2d [internal slots]\n", 0 , nof_internal_slots - 1);
 
470
    }
 
471
    for (int i = nof_internal_slots; start < end; ++i, ++start) {
 
472
      PrintF("  %2d ", i);
 
473
      String::cast(scope_info->get(start))->ShortPrint();
 
474
      PrintF("\n");
 
475
    }
 
476
  }
 
477
}
 
478
 
 
479
 
 
480
void ScopeInfo::Print() {
 
481
  PrintF("ScopeInfo ");
 
482
  if (HasFunctionName()) {
 
483
    FunctionName()->ShortPrint();
 
484
  } else {
 
485
    PrintF("/* no function name */");
 
486
  }
 
487
  PrintF("{");
 
488
 
 
489
  PrintList("parameters", 0,
 
490
            ParameterEntriesIndex(),
 
491
            ParameterEntriesIndex() + ParameterCount(),
 
492
            this);
 
493
  PrintList("stack slots", 0,
 
494
            StackLocalEntriesIndex(),
 
495
            StackLocalEntriesIndex() + StackLocalCount(),
 
496
            this);
 
497
  PrintList("context slots",
 
498
            Context::MIN_CONTEXT_SLOTS,
 
499
            ContextLocalNameEntriesIndex(),
 
500
            ContextLocalNameEntriesIndex() + ContextLocalCount(),
 
501
            this);
 
502
 
 
503
  PrintF("}\n");
 
504
}
 
505
#endif  // DEBUG
 
506
 
 
507
} }  // namespace v8::internal