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

« back to all changes in this revision

Viewing changes to src/third_party/v8/src/code-stubs.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 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 "bootstrapper.h"
 
31
#include "code-stubs.h"
 
32
#include "stub-cache.h"
 
33
#include "factory.h"
 
34
#include "gdb-jit.h"
 
35
#include "macro-assembler.h"
 
36
 
 
37
namespace v8 {
 
38
namespace internal {
 
39
 
 
40
bool CodeStub::FindCodeInCache(Code** code_out) {
 
41
  Heap* heap = Isolate::Current()->heap();
 
42
  int index = heap->code_stubs()->FindEntry(GetKey());
 
43
  if (index != UnseededNumberDictionary::kNotFound) {
 
44
    *code_out = Code::cast(heap->code_stubs()->ValueAt(index));
 
45
    return true;
 
46
  }
 
47
  return false;
 
48
}
 
49
 
 
50
 
 
51
void CodeStub::GenerateCode(MacroAssembler* masm) {
 
52
  // Update the static counter each time a new code stub is generated.
 
53
  masm->isolate()->counters()->code_stubs()->Increment();
 
54
 
 
55
  // Nested stubs are not allowed for leaves.
 
56
  AllowStubCallsScope allow_scope(masm, false);
 
57
 
 
58
  // Generate the code for the stub.
 
59
  masm->set_generating_stub(true);
 
60
  NoCurrentFrameScope scope(masm);
 
61
  Generate(masm);
 
62
}
 
63
 
 
64
 
 
65
SmartArrayPointer<const char> CodeStub::GetName() {
 
66
  char buffer[100];
 
67
  NoAllocationStringAllocator allocator(buffer,
 
68
                                        static_cast<unsigned>(sizeof(buffer)));
 
69
  StringStream stream(&allocator);
 
70
  PrintName(&stream);
 
71
  return stream.ToCString();
 
72
}
 
73
 
 
74
 
 
75
void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
 
76
  Isolate* isolate = masm->isolate();
 
77
  SmartArrayPointer<const char> name = GetName();
 
78
  PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
 
79
  GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
 
80
  Counters* counters = isolate->counters();
 
81
  counters->total_stubs_code_size()->Increment(code->instruction_size());
 
82
}
 
83
 
 
84
 
 
85
int CodeStub::GetCodeKind() {
 
86
  return Code::STUB;
 
87
}
 
88
 
 
89
 
 
90
Handle<Code> CodeStub::GetCode() {
 
91
  Isolate* isolate = Isolate::Current();
 
92
  Factory* factory = isolate->factory();
 
93
  Heap* heap = isolate->heap();
 
94
  Code* code;
 
95
  if (UseSpecialCache()
 
96
      ? FindCodeInSpecialCache(&code)
 
97
      : FindCodeInCache(&code)) {
 
98
    ASSERT(IsPregenerated() == code->is_pregenerated());
 
99
    return Handle<Code>(code);
 
100
  }
 
101
 
 
102
  {
 
103
    HandleScope scope(isolate);
 
104
 
 
105
    // Generate the new code.
 
106
    MacroAssembler masm(isolate, NULL, 256);
 
107
    GenerateCode(&masm);
 
108
 
 
109
    // Create the code object.
 
110
    CodeDesc desc;
 
111
    masm.GetCode(&desc);
 
112
 
 
113
    // Copy the generated code into a heap object.
 
114
    Code::Flags flags = Code::ComputeFlags(
 
115
        static_cast<Code::Kind>(GetCodeKind()),
 
116
        GetICState());
 
117
    Handle<Code> new_object = factory->NewCode(
 
118
        desc, flags, masm.CodeObject(), NeedsImmovableCode());
 
119
    new_object->set_major_key(MajorKey());
 
120
    FinishCode(new_object);
 
121
    RecordCodeGeneration(*new_object, &masm);
 
122
 
 
123
#ifdef ENABLE_DISASSEMBLER
 
124
    if (FLAG_print_code_stubs) {
 
125
      new_object->Disassemble(*GetName());
 
126
      PrintF("\n");
 
127
    }
 
128
#endif
 
129
 
 
130
    if (UseSpecialCache()) {
 
131
      AddToSpecialCache(new_object);
 
132
    } else {
 
133
      // Update the dictionary and the root in Heap.
 
134
      Handle<UnseededNumberDictionary> dict =
 
135
          factory->DictionaryAtNumberPut(
 
136
              Handle<UnseededNumberDictionary>(heap->code_stubs()),
 
137
              GetKey(),
 
138
              new_object);
 
139
      heap->public_set_code_stubs(*dict);
 
140
    }
 
141
    code = *new_object;
 
142
  }
 
143
 
 
144
  Activate(code);
 
145
  ASSERT(!NeedsImmovableCode() || heap->lo_space()->Contains(code));
 
146
  return Handle<Code>(code, isolate);
 
147
}
 
148
 
 
149
 
 
150
const char* CodeStub::MajorName(CodeStub::Major major_key,
 
151
                                bool allow_unknown_keys) {
 
152
  switch (major_key) {
 
153
#define DEF_CASE(name) case name: return #name "Stub";
 
154
    CODE_STUB_LIST(DEF_CASE)
 
155
#undef DEF_CASE
 
156
    default:
 
157
      if (!allow_unknown_keys) {
 
158
        UNREACHABLE();
 
159
      }
 
160
      return NULL;
 
161
  }
 
162
}
 
163
 
 
164
 
 
165
void CodeStub::PrintName(StringStream* stream) {
 
166
  stream->Add("%s", MajorName(MajorKey(), false));
 
167
}
 
168
 
 
169
 
 
170
void ICCompareStub::AddToSpecialCache(Handle<Code> new_object) {
 
171
  ASSERT(*known_map_ != NULL);
 
172
  Isolate* isolate = new_object->GetIsolate();
 
173
  Factory* factory = isolate->factory();
 
174
  return Map::UpdateCodeCache(known_map_,
 
175
                              strict() ?
 
176
                                  factory->strict_compare_ic_symbol() :
 
177
                                  factory->compare_ic_symbol(),
 
178
                              new_object);
 
179
}
 
180
 
 
181
 
 
182
bool ICCompareStub::FindCodeInSpecialCache(Code** code_out) {
 
183
  Isolate* isolate = known_map_->GetIsolate();
 
184
  Factory* factory = isolate->factory();
 
185
  Code::Flags flags = Code::ComputeFlags(
 
186
      static_cast<Code::Kind>(GetCodeKind()),
 
187
      UNINITIALIZED);
 
188
  ASSERT(op_ == Token::EQ || op_ == Token::EQ_STRICT);
 
189
  Handle<Object> probe(
 
190
      known_map_->FindInCodeCache(
 
191
        strict() ?
 
192
            *factory->strict_compare_ic_symbol() :
 
193
            *factory->compare_ic_symbol(),
 
194
        flags));
 
195
  if (probe->IsCode()) {
 
196
    *code_out = Code::cast(*probe);
 
197
    ASSERT(op_ == (*code_out)->compare_operation() + Token::EQ);
 
198
    return true;
 
199
  }
 
200
  return false;
 
201
}
 
202
 
 
203
 
 
204
int ICCompareStub::MinorKey() {
 
205
  return OpField::encode(op_ - Token::EQ) | StateField::encode(state_);
 
206
}
 
207
 
 
208
 
 
209
void ICCompareStub::Generate(MacroAssembler* masm) {
 
210
  switch (state_) {
 
211
    case CompareIC::UNINITIALIZED:
 
212
      GenerateMiss(masm);
 
213
      break;
 
214
    case CompareIC::SMIS:
 
215
      GenerateSmis(masm);
 
216
      break;
 
217
    case CompareIC::HEAP_NUMBERS:
 
218
      GenerateHeapNumbers(masm);
 
219
      break;
 
220
    case CompareIC::STRINGS:
 
221
      GenerateStrings(masm);
 
222
      break;
 
223
    case CompareIC::SYMBOLS:
 
224
      GenerateSymbols(masm);
 
225
      break;
 
226
    case CompareIC::OBJECTS:
 
227
      GenerateObjects(masm);
 
228
      break;
 
229
    case CompareIC::KNOWN_OBJECTS:
 
230
      ASSERT(*known_map_ != NULL);
 
231
      GenerateKnownObjects(masm);
 
232
      break;
 
233
    default:
 
234
      UNREACHABLE();
 
235
  }
 
236
}
 
237
 
 
238
 
 
239
void InstanceofStub::PrintName(StringStream* stream) {
 
240
  const char* args = "";
 
241
  if (HasArgsInRegisters()) {
 
242
    args = "_REGS";
 
243
  }
 
244
 
 
245
  const char* inline_check = "";
 
246
  if (HasCallSiteInlineCheck()) {
 
247
    inline_check = "_INLINE";
 
248
  }
 
249
 
 
250
  const char* return_true_false_object = "";
 
251
  if (ReturnTrueFalseObject()) {
 
252
    return_true_false_object = "_TRUEFALSE";
 
253
  }
 
254
 
 
255
  stream->Add("InstanceofStub%s%s%s",
 
256
              args,
 
257
              inline_check,
 
258
              return_true_false_object);
 
259
}
 
260
 
 
261
 
 
262
void JSEntryStub::FinishCode(Handle<Code> code) {
 
263
  Handle<FixedArray> handler_table =
 
264
      code->GetIsolate()->factory()->NewFixedArray(1, TENURED);
 
265
  handler_table->set(0, Smi::FromInt(handler_offset_));
 
266
  code->set_handler_table(*handler_table);
 
267
}
 
268
 
 
269
 
 
270
void KeyedLoadElementStub::Generate(MacroAssembler* masm) {
 
271
  switch (elements_kind_) {
 
272
    case FAST_ELEMENTS:
 
273
    case FAST_HOLEY_ELEMENTS:
 
274
    case FAST_SMI_ELEMENTS:
 
275
    case FAST_HOLEY_SMI_ELEMENTS:
 
276
      KeyedLoadStubCompiler::GenerateLoadFastElement(masm);
 
277
      break;
 
278
    case FAST_DOUBLE_ELEMENTS:
 
279
    case FAST_HOLEY_DOUBLE_ELEMENTS:
 
280
      KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm);
 
281
      break;
 
282
    case EXTERNAL_BYTE_ELEMENTS:
 
283
    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
 
284
    case EXTERNAL_SHORT_ELEMENTS:
 
285
    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
 
286
    case EXTERNAL_INT_ELEMENTS:
 
287
    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
 
288
    case EXTERNAL_FLOAT_ELEMENTS:
 
289
    case EXTERNAL_DOUBLE_ELEMENTS:
 
290
    case EXTERNAL_PIXEL_ELEMENTS:
 
291
      KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_);
 
292
      break;
 
293
    case DICTIONARY_ELEMENTS:
 
294
      KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
 
295
      break;
 
296
    case NON_STRICT_ARGUMENTS_ELEMENTS:
 
297
      UNREACHABLE();
 
298
      break;
 
299
  }
 
300
}
 
301
 
 
302
 
 
303
void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
 
304
  switch (elements_kind_) {
 
305
    case FAST_ELEMENTS:
 
306
    case FAST_HOLEY_ELEMENTS:
 
307
    case FAST_SMI_ELEMENTS:
 
308
    case FAST_HOLEY_SMI_ELEMENTS: {
 
309
      KeyedStoreStubCompiler::GenerateStoreFastElement(masm,
 
310
                                                       is_js_array_,
 
311
                                                       elements_kind_,
 
312
                                                       grow_mode_);
 
313
    }
 
314
      break;
 
315
    case FAST_DOUBLE_ELEMENTS:
 
316
    case FAST_HOLEY_DOUBLE_ELEMENTS:
 
317
      KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
 
318
                                                             is_js_array_,
 
319
                                                             grow_mode_);
 
320
      break;
 
321
    case EXTERNAL_BYTE_ELEMENTS:
 
322
    case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
 
323
    case EXTERNAL_SHORT_ELEMENTS:
 
324
    case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
 
325
    case EXTERNAL_INT_ELEMENTS:
 
326
    case EXTERNAL_UNSIGNED_INT_ELEMENTS:
 
327
    case EXTERNAL_FLOAT_ELEMENTS:
 
328
    case EXTERNAL_DOUBLE_ELEMENTS:
 
329
    case EXTERNAL_PIXEL_ELEMENTS:
 
330
      KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_);
 
331
      break;
 
332
    case DICTIONARY_ELEMENTS:
 
333
      KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm);
 
334
      break;
 
335
    case NON_STRICT_ARGUMENTS_ELEMENTS:
 
336
      UNREACHABLE();
 
337
      break;
 
338
  }
 
339
}
 
340
 
 
341
 
 
342
void ArgumentsAccessStub::PrintName(StringStream* stream) {
 
343
  stream->Add("ArgumentsAccessStub_");
 
344
  switch (type_) {
 
345
    case READ_ELEMENT: stream->Add("ReadElement"); break;
 
346
    case NEW_NON_STRICT_FAST: stream->Add("NewNonStrictFast"); break;
 
347
    case NEW_NON_STRICT_SLOW: stream->Add("NewNonStrictSlow"); break;
 
348
    case NEW_STRICT: stream->Add("NewStrict"); break;
 
349
  }
 
350
}
 
351
 
 
352
 
 
353
void CallFunctionStub::PrintName(StringStream* stream) {
 
354
  stream->Add("CallFunctionStub_Args%d", argc_);
 
355
  if (ReceiverMightBeImplicit()) stream->Add("_Implicit");
 
356
  if (RecordCallTarget()) stream->Add("_Recording");
 
357
}
 
358
 
 
359
 
 
360
void CallConstructStub::PrintName(StringStream* stream) {
 
361
  stream->Add("CallConstructStub");
 
362
  if (RecordCallTarget()) stream->Add("_Recording");
 
363
}
 
364
 
 
365
 
 
366
void ToBooleanStub::PrintName(StringStream* stream) {
 
367
  stream->Add("ToBooleanStub_");
 
368
  types_.Print(stream);
 
369
}
 
370
 
 
371
 
 
372
void ToBooleanStub::Types::Print(StringStream* stream) const {
 
373
  if (IsEmpty()) stream->Add("None");
 
374
  if (Contains(UNDEFINED)) stream->Add("Undefined");
 
375
  if (Contains(BOOLEAN)) stream->Add("Bool");
 
376
  if (Contains(NULL_TYPE)) stream->Add("Null");
 
377
  if (Contains(SMI)) stream->Add("Smi");
 
378
  if (Contains(SPEC_OBJECT)) stream->Add("SpecObject");
 
379
  if (Contains(STRING)) stream->Add("String");
 
380
  if (Contains(HEAP_NUMBER)) stream->Add("HeapNumber");
 
381
}
 
382
 
 
383
 
 
384
void ToBooleanStub::Types::TraceTransition(Types to) const {
 
385
  if (!FLAG_trace_ic) return;
 
386
  char buffer[100];
 
387
  NoAllocationStringAllocator allocator(buffer,
 
388
                                        static_cast<unsigned>(sizeof(buffer)));
 
389
  StringStream stream(&allocator);
 
390
  stream.Add("[ToBooleanIC (");
 
391
  Print(&stream);
 
392
  stream.Add("->");
 
393
  to.Print(&stream);
 
394
  stream.Add(")]\n");
 
395
  stream.OutputToStdOut();
 
396
}
 
397
 
 
398
 
 
399
bool ToBooleanStub::Types::Record(Handle<Object> object) {
 
400
  if (object->IsUndefined()) {
 
401
    Add(UNDEFINED);
 
402
    return false;
 
403
  } else if (object->IsBoolean()) {
 
404
    Add(BOOLEAN);
 
405
    return object->IsTrue();
 
406
  } else if (object->IsNull()) {
 
407
    Add(NULL_TYPE);
 
408
    return false;
 
409
  } else if (object->IsSmi()) {
 
410
    Add(SMI);
 
411
    return Smi::cast(*object)->value() != 0;
 
412
  } else if (object->IsSpecObject()) {
 
413
    Add(SPEC_OBJECT);
 
414
    return !object->IsUndetectableObject();
 
415
  } else if (object->IsString()) {
 
416
    Add(STRING);
 
417
    return !object->IsUndetectableObject() &&
 
418
        String::cast(*object)->length() != 0;
 
419
  } else if (object->IsHeapNumber()) {
 
420
    ASSERT(!object->IsUndetectableObject());
 
421
    Add(HEAP_NUMBER);
 
422
    double value = HeapNumber::cast(*object)->value();
 
423
    return value != 0 && !isnan(value);
 
424
  } else {
 
425
    // We should never see an internal object at runtime here!
 
426
    UNREACHABLE();
 
427
    return true;
 
428
  }
 
429
}
 
430
 
 
431
 
 
432
bool ToBooleanStub::Types::NeedsMap() const {
 
433
  return Contains(ToBooleanStub::SPEC_OBJECT)
 
434
      || Contains(ToBooleanStub::STRING)
 
435
      || Contains(ToBooleanStub::HEAP_NUMBER);
 
436
}
 
437
 
 
438
 
 
439
bool ToBooleanStub::Types::CanBeUndetectable() const {
 
440
  return Contains(ToBooleanStub::SPEC_OBJECT)
 
441
      || Contains(ToBooleanStub::STRING);
 
442
}
 
443
 
 
444
 
 
445
void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) {
 
446
  Label fail;
 
447
  ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_));
 
448
  if (!FLAG_trace_elements_transitions) {
 
449
    if (IsFastSmiOrObjectElementsKind(to_)) {
 
450
      if (IsFastSmiOrObjectElementsKind(from_)) {
 
451
        ElementsTransitionGenerator::
 
452
            GenerateMapChangeElementsTransition(masm);
 
453
      } else if (IsFastDoubleElementsKind(from_)) {
 
454
        ASSERT(!IsFastSmiElementsKind(to_));
 
455
        ElementsTransitionGenerator::GenerateDoubleToObject(masm, &fail);
 
456
      } else {
 
457
        UNREACHABLE();
 
458
      }
 
459
      KeyedStoreStubCompiler::GenerateStoreFastElement(masm,
 
460
                                                       is_jsarray_,
 
461
                                                       to_,
 
462
                                                       grow_mode_);
 
463
    } else if (IsFastSmiElementsKind(from_) &&
 
464
               IsFastDoubleElementsKind(to_)) {
 
465
      ElementsTransitionGenerator::GenerateSmiToDouble(masm, &fail);
 
466
      KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
 
467
                                                             is_jsarray_,
 
468
                                                             grow_mode_);
 
469
    } else if (IsFastDoubleElementsKind(from_)) {
 
470
      ASSERT(to_ == FAST_HOLEY_DOUBLE_ELEMENTS);
 
471
      ElementsTransitionGenerator::
 
472
          GenerateMapChangeElementsTransition(masm);
 
473
    } else {
 
474
      UNREACHABLE();
 
475
    }
 
476
  }
 
477
  masm->bind(&fail);
 
478
  KeyedStoreIC::GenerateRuntimeSetProperty(masm, strict_mode_);
 
479
}
 
480
 
 
481
 
 
482
FunctionEntryHook ProfileEntryHookStub::entry_hook_ = NULL;
 
483
 
 
484
 
 
485
void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function,
 
486
                                               intptr_t stack_pointer) {
 
487
  if (entry_hook_ != NULL)
 
488
    entry_hook_(function, stack_pointer);
 
489
}
 
490
 
 
491
 
 
492
bool ProfileEntryHookStub::SetFunctionEntryHook(FunctionEntryHook entry_hook) {
 
493
  // We don't allow setting a new entry hook over one that's
 
494
  // already active, as the hooks won't stack.
 
495
  if (entry_hook != 0 && entry_hook_ != 0)
 
496
    return false;
 
497
 
 
498
  entry_hook_ = entry_hook;
 
499
  return true;
 
500
}
 
501
 
 
502
 
 
503
} }  // namespace v8::internal