Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Unified Diff: src/builtins.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/builtins.h ('k') | src/checks.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
===================================================================
--- src/builtins.cc (revision 7267)
+++ src/builtins.cc (working copy)
@@ -107,7 +107,6 @@
} // namespace
-
// ----------------------------------------------------------------------------
// Support macro for defining builtins in C++.
// ----------------------------------------------------------------------------
@@ -123,26 +122,27 @@
#ifdef DEBUG
-#define BUILTIN(name) \
- MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
- name##ArgumentsType args); \
- MUST_USE_RESULT static MaybeObject* Builtin_##name( \
- name##ArgumentsType args) { \
- args.Verify(); \
- return Builtin_Impl_##name(args); \
- } \
- MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
- name##ArgumentsType args)
+#define BUILTIN(name) \
+ MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
+ name##ArgumentsType args, Isolate* isolate); \
+ MUST_USE_RESULT static MaybeObject* Builtin_##name( \
+ name##ArgumentsType args, Isolate* isolate) { \
+ ASSERT(isolate == Isolate::Current()); \
+ args.Verify(); \
+ return Builtin_Impl_##name(args, isolate); \
+ } \
+ MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \
+ name##ArgumentsType args, Isolate* isolate)
#else // For release mode.
-#define BUILTIN(name) \
- static MaybeObject* Builtin_##name(name##ArgumentsType args)
+#define BUILTIN(name) \
+ static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate)
#endif
-static inline bool CalledAsConstructor() {
+static inline bool CalledAsConstructor(Isolate* isolate) {
#ifdef DEBUG
// Calculate the result using a full stack frame iterator and check
// that the state of the stack is as we assume it to be in the
@@ -153,7 +153,7 @@
StackFrame* frame = it.frame();
bool reference_result = frame->is_construct();
#endif
- Address fp = Top::c_entry_fp(Top::GetCurrentThread());
+ Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
// Because we know fp points to an exit frame we can use the relevant
// part of ExitFrame::ComputeCallerState directly.
const int kCallerOffset = ExitFrameConstants::kCallerFPOffset;
@@ -172,30 +172,30 @@
// ----------------------------------------------------------------------------
-
BUILTIN(Illegal) {
UNREACHABLE();
- return Heap::undefined_value(); // Make compiler happy.
+ return isolate->heap()->undefined_value(); // Make compiler happy.
}
BUILTIN(EmptyFunction) {
- return Heap::undefined_value();
+ return isolate->heap()->undefined_value();
}
BUILTIN(ArrayCodeGeneric) {
- Counters::array_function_runtime.Increment();
+ Heap* heap = isolate->heap();
+ isolate->counters()->array_function_runtime()->Increment();
JSArray* array;
- if (CalledAsConstructor()) {
+ if (CalledAsConstructor(isolate)) {
array = JSArray::cast(*args.receiver());
} else {
// Allocate the JS Array
JSFunction* constructor =
- Top::context()->global_context()->array_function();
+ isolate->context()->global_context()->array_function();
Object* obj;
- { MaybeObject* maybe_obj = Heap::AllocateJSObject(constructor);
+ { MaybeObject* maybe_obj = heap->AllocateJSObject(constructor);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
array = JSArray::cast(obj);
@@ -212,7 +212,7 @@
int len = Smi::cast(obj)->value();
if (len >= 0 && len < JSObject::kInitialMaxFastElementArray) {
Object* obj;
- { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(len);
+ { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
array->SetContent(FixedArray::cast(obj));
@@ -235,7 +235,7 @@
int number_of_elements = args.length() - 1;
Smi* len = Smi::FromInt(number_of_elements);
Object* obj;
- { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(len->value());
+ { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(len->value());
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
@@ -255,77 +255,81 @@
}
-MUST_USE_RESULT static MaybeObject* AllocateJSArray() {
+MUST_USE_RESULT static MaybeObject* AllocateJSArray(Heap* heap) {
JSFunction* array_function =
- Top::context()->global_context()->array_function();
+ heap->isolate()->context()->global_context()->array_function();
Object* result;
- { MaybeObject* maybe_result = Heap::AllocateJSObject(array_function);
+ { MaybeObject* maybe_result = heap->AllocateJSObject(array_function);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
return result;
}
-MUST_USE_RESULT static MaybeObject* AllocateEmptyJSArray() {
+MUST_USE_RESULT static MaybeObject* AllocateEmptyJSArray(Heap* heap) {
Object* result;
- { MaybeObject* maybe_result = AllocateJSArray();
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
JSArray* result_array = JSArray::cast(result);
result_array->set_length(Smi::FromInt(0));
- result_array->set_elements(Heap::empty_fixed_array());
+ result_array->set_elements(heap->empty_fixed_array());
return result_array;
}
-static void CopyElements(AssertNoAllocation* no_gc,
+static void CopyElements(Heap* heap,
+ AssertNoAllocation* no_gc,
FixedArray* dst,
int dst_index,
FixedArray* src,
int src_index,
int len) {
ASSERT(dst != src); // Use MoveElements instead.
- ASSERT(dst->map() != Heap::fixed_cow_array_map());
+ ASSERT(dst->map() != HEAP->fixed_cow_array_map());
ASSERT(len > 0);
CopyWords(dst->data_start() + dst_index,
src->data_start() + src_index,
len);
WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
if (mode == UPDATE_WRITE_BARRIER) {
- Heap::RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
+ heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
}
}
-static void MoveElements(AssertNoAllocation* no_gc,
+static void MoveElements(Heap* heap,
+ AssertNoAllocation* no_gc,
FixedArray* dst,
int dst_index,
FixedArray* src,
int src_index,
int len) {
- ASSERT(dst->map() != Heap::fixed_cow_array_map());
+ ASSERT(dst->map() != HEAP->fixed_cow_array_map());
memmove(dst->data_start() + dst_index,
src->data_start() + src_index,
len * kPointerSize);
WriteBarrierMode mode = dst->GetWriteBarrierMode(*no_gc);
if (mode == UPDATE_WRITE_BARRIER) {
- Heap::RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
+ heap->RecordWrites(dst->address(), dst->OffsetOfElementAt(dst_index), len);
}
}
-static void FillWithHoles(FixedArray* dst, int from, int to) {
- ASSERT(dst->map() != Heap::fixed_cow_array_map());
- MemsetPointer(dst->data_start() + from, Heap::the_hole_value(), to - from);
+static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
+ ASSERT(dst->map() != heap->fixed_cow_array_map());
+ MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
}
-static FixedArray* LeftTrimFixedArray(FixedArray* elms, int to_trim) {
- ASSERT(elms->map() != Heap::fixed_cow_array_map());
+static FixedArray* LeftTrimFixedArray(Heap* heap,
+ FixedArray* elms,
+ int to_trim) {
+ ASSERT(elms->map() != HEAP->fixed_cow_array_map());
// For now this trick is only applied to fixed arrays in new and paged space.
// In large object space the object's start must coincide with chunk
// and thus the trick is just not applicable.
- ASSERT(!Heap::lo_space()->Contains(elms));
+ ASSERT(!HEAP->lo_space()->Contains(elms));
STATIC_ASSERT(FixedArray::kMapOffset == 0);
STATIC_ASSERT(FixedArray::kLengthOffset == kPointerSize);
@@ -336,7 +340,7 @@
const int len = elms->length();
if (to_trim > FixedArray::kHeaderSize / kPointerSize &&
- !Heap::new_space()->Contains(elms)) {
+ !heap->new_space()->Contains(elms)) {
// If we are doing a big trim in old space then we zap the space that was
// formerly part of the array so that the GC (aided by the card-based
// remembered set) won't find pointers to new-space there.
@@ -349,9 +353,9 @@
// Technically in new space this write might be omitted (except for
// debug mode which iterates through the heap), but to play safer
// we still do it.
- Heap::CreateFillerObjectAt(elms->address(), to_trim * kPointerSize);
+ heap->CreateFillerObjectAt(elms->address(), to_trim * kPointerSize);
- former_start[to_trim] = Heap::fixed_array_map();
+ former_start[to_trim] = heap->fixed_array_map();
former_start[to_trim + 1] = Smi::FromInt(len - to_trim);
return FixedArray::cast(HeapObject::FromAddress(
@@ -359,20 +363,21 @@
}
-static bool ArrayPrototypeHasNoElements(Context* global_context,
+static bool ArrayPrototypeHasNoElements(Heap* heap,
+ Context* global_context,
JSObject* array_proto) {
// This method depends on non writability of Object and Array prototype
// fields.
- if (array_proto->elements() != Heap::empty_fixed_array()) return false;
+ if (array_proto->elements() != heap->empty_fixed_array()) return false;
// Hidden prototype
array_proto = JSObject::cast(array_proto->GetPrototype());
- ASSERT(array_proto->elements() == Heap::empty_fixed_array());
+ ASSERT(array_proto->elements() == heap->empty_fixed_array());
// Object.prototype
Object* proto = array_proto->GetPrototype();
- if (proto == Heap::null_value()) return false;
+ if (proto == heap->null_value()) return false;
array_proto = JSObject::cast(proto);
if (array_proto != global_context->initial_object_prototype()) return false;
- if (array_proto->elements() != Heap::empty_fixed_array()) return false;
+ if (array_proto->elements() != heap->empty_fixed_array()) return false;
ASSERT(array_proto->GetPrototype()->IsNull());
return true;
}
@@ -380,35 +385,38 @@
MUST_USE_RESULT
static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
- Object* receiver) {
+ Heap* heap, Object* receiver) {
if (!receiver->IsJSArray()) return NULL;
JSArray* array = JSArray::cast(receiver);
HeapObject* elms = array->elements();
- if (elms->map() == Heap::fixed_array_map()) return elms;
- if (elms->map() == Heap::fixed_cow_array_map()) {
+ if (elms->map() == heap->fixed_array_map()) return elms;
+ if (elms->map() == heap->fixed_cow_array_map()) {
return array->EnsureWritableFastElements();
}
return NULL;
}
-static inline bool IsJSArrayFastElementMovingAllowed(JSArray* receiver) {
- Context* global_context = Top::context()->global_context();
+static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
+ JSArray* receiver) {
+ Context* global_context = heap->isolate()->context()->global_context();
JSObject* array_proto =
JSObject::cast(global_context->array_function()->prototype());
return receiver->GetPrototype() == array_proto &&
- ArrayPrototypeHasNoElements(global_context, array_proto);
+ ArrayPrototypeHasNoElements(heap, global_context, array_proto);
}
MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
+ Isolate* isolate,
const char* name,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
- HandleScope handleScope;
+ HandleScope handleScope(isolate);
Handle<Object> js_builtin =
- GetProperty(Handle<JSObject>(Top::global_context()->builtins()),
- name);
+ GetProperty(Handle<JSObject>(
+ isolate->global_context()->builtins()),
+ name);
ASSERT(js_builtin->IsJSFunction());
Handle<JSFunction> function(Handle<JSFunction>::cast(js_builtin));
ScopedVector<Object**> argv(args.length() - 1);
@@ -428,11 +436,14 @@
BUILTIN(ArrayPush) {
+ Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
Object* elms_obj;
{ MaybeObject* maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(receiver);
- if (maybe_elms_obj == NULL) return CallJsBuiltin("ArrayPush", args);
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
+ if (maybe_elms_obj == NULL) {
+ return CallJsBuiltin(isolate, "ArrayPush", args);
+ }
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
}
FixedArray* elms = FixedArray::cast(elms_obj);
@@ -453,16 +464,16 @@
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
Object* obj;
- { MaybeObject* maybe_obj = Heap::AllocateUninitializedFixedArray(capacity);
+ { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
FixedArray* new_elms = FixedArray::cast(obj);
AssertNoAllocation no_gc;
if (len > 0) {
- CopyElements(&no_gc, new_elms, 0, elms, 0, len);
+ CopyElements(heap, &no_gc, new_elms, 0, elms, 0, len);
}
- FillWithHoles(new_elms, new_length, capacity);
+ FillWithHoles(heap, new_elms, new_length, capacity);
elms = new_elms;
array->set_elements(elms);
@@ -482,18 +493,19 @@
BUILTIN(ArrayPop) {
+ Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
Object* elms_obj;
{ MaybeObject* maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(receiver);
- if (maybe_elms_obj == NULL) return CallJsBuiltin("ArrayPop", args);
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
+ if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
}
FixedArray* elms = FixedArray::cast(elms_obj);
JSArray* array = JSArray::cast(receiver);
int len = Smi::cast(array->length())->value();
- if (len == 0) return Heap::undefined_value();
+ if (len == 0) return heap->undefined_value();
// Get top element
MaybeObject* top = elms->get(len - 1);
@@ -514,38 +526,40 @@
BUILTIN(ArrayShift) {
+ Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
Object* elms_obj;
{ MaybeObject* maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(receiver);
- if (maybe_elms_obj == NULL) return CallJsBuiltin("ArrayShift", args);
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
+ if (maybe_elms_obj == NULL)
+ return CallJsBuiltin(isolate, "ArrayShift", args);
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
}
- if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
- return CallJsBuiltin("ArrayShift", args);
+ if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
+ return CallJsBuiltin(isolate, "ArrayShift", args);
}
FixedArray* elms = FixedArray::cast(elms_obj);
JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
- if (len == 0) return Heap::undefined_value();
+ if (len == 0) return heap->undefined_value();
// Get first element
Object* first = elms->get(0);
if (first->IsTheHole()) {
- first = Heap::undefined_value();
+ first = heap->undefined_value();
}
- if (!Heap::lo_space()->Contains(elms)) {
+ if (!heap->lo_space()->Contains(elms)) {
// As elms still in the same space they used to be,
// there is no need to update region dirty mark.
- array->set_elements(LeftTrimFixedArray(elms, 1), SKIP_WRITE_BARRIER);
+ array->set_elements(LeftTrimFixedArray(heap, elms, 1), SKIP_WRITE_BARRIER);
} else {
// Shift the elements.
AssertNoAllocation no_gc;
- MoveElements(&no_gc, elms, 0, elms, 1, len - 1);
- elms->set(len - 1, Heap::the_hole_value());
+ MoveElements(heap, &no_gc, elms, 0, elms, 1, len - 1);
+ elms->set(len - 1, heap->the_hole_value());
}
// Set the length.
@@ -556,15 +570,17 @@
BUILTIN(ArrayUnshift) {
+ Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
Object* elms_obj;
{ MaybeObject* maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(receiver);
- if (maybe_elms_obj == NULL) return CallJsBuiltin("ArrayUnshift", args);
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
+ if (maybe_elms_obj == NULL)
+ return CallJsBuiltin(isolate, "ArrayUnshift", args);
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
}
- if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
- return CallJsBuiltin("ArrayUnshift", args);
+ if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
+ return CallJsBuiltin(isolate, "ArrayUnshift", args);
}
FixedArray* elms = FixedArray::cast(elms_obj);
JSArray* array = JSArray::cast(receiver);
@@ -581,22 +597,22 @@
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
Object* obj;
- { MaybeObject* maybe_obj = Heap::AllocateUninitializedFixedArray(capacity);
+ { MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
FixedArray* new_elms = FixedArray::cast(obj);
AssertNoAllocation no_gc;
if (len > 0) {
- CopyElements(&no_gc, new_elms, to_add, elms, 0, len);
+ CopyElements(heap, &no_gc, new_elms, to_add, elms, 0, len);
}
- FillWithHoles(new_elms, new_length, capacity);
+ FillWithHoles(heap, new_elms, new_length, capacity);
elms = new_elms;
array->set_elements(elms);
} else {
AssertNoAllocation no_gc;
- MoveElements(&no_gc, elms, to_add, elms, 0, len);
+ MoveElements(heap, &no_gc, elms, to_add, elms, 0, len);
}
// Add the provided values.
@@ -613,14 +629,15 @@
BUILTIN(ArraySlice) {
+ Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
FixedArray* elms;
int len = -1;
if (receiver->IsJSArray()) {
JSArray* array = JSArray::cast(receiver);
if (!array->HasFastElements() ||
- !IsJSArrayFastElementMovingAllowed(array)) {
- return CallJsBuiltin("ArraySlice", args);
+ !IsJSArrayFastElementMovingAllowed(heap, array)) {
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
elms = FixedArray::cast(array->elements());
@@ -629,28 +646,28 @@
// Array.slice(arguments, ...) is quite a common idiom (notably more
// than 50% of invocations in Web apps). Treat it in C++ as well.
Map* arguments_map =
- Top::context()->global_context()->arguments_boilerplate()->map();
+ isolate->context()->global_context()->arguments_boilerplate()->map();
bool is_arguments_object_with_fast_elements =
receiver->IsJSObject()
&& JSObject::cast(receiver)->map() == arguments_map
&& JSObject::cast(receiver)->HasFastElements();
if (!is_arguments_object_with_fast_elements) {
- return CallJsBuiltin("ArraySlice", args);
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
elms = FixedArray::cast(JSObject::cast(receiver)->elements());
Object* len_obj = JSObject::cast(receiver)
->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
if (!len_obj->IsSmi()) {
- return CallJsBuiltin("ArraySlice", args);
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
len = Smi::cast(len_obj)->value();
if (len > elms->length()) {
- return CallJsBuiltin("ArraySlice", args);
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
for (int i = 0; i < len; i++) {
- if (elms->get(i) == Heap::the_hole_value()) {
- return CallJsBuiltin("ArraySlice", args);
+ if (elms->get(i) == heap->the_hole_value()) {
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
}
}
@@ -667,14 +684,14 @@
if (arg1->IsSmi()) {
relative_start = Smi::cast(arg1)->value();
} else if (!arg1->IsUndefined()) {
- return CallJsBuiltin("ArraySlice", args);
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
if (n_arguments > 1) {
Object* arg2 = args[2];
if (arg2->IsSmi()) {
relative_end = Smi::cast(arg2)->value();
} else if (!arg2->IsUndefined()) {
- return CallJsBuiltin("ArraySlice", args);
+ return CallJsBuiltin(isolate, "ArraySlice", args);
}
}
}
@@ -690,23 +707,23 @@
// Calculate the length of result array.
int result_len = final - k;
if (result_len <= 0) {
- return AllocateEmptyJSArray();
+ return AllocateEmptyJSArray(heap);
}
Object* result;
- { MaybeObject* maybe_result = AllocateJSArray();
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
JSArray* result_array = JSArray::cast(result);
{ MaybeObject* maybe_result =
- Heap::AllocateUninitializedFixedArray(result_len);
+ heap->AllocateUninitializedFixedArray(result_len);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
FixedArray* result_elms = FixedArray::cast(result);
AssertNoAllocation no_gc;
- CopyElements(&no_gc, result_elms, 0, elms, k, result_len);
+ CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len);
// Set elements.
result_array->set_elements(result_elms);
@@ -718,15 +735,17 @@
BUILTIN(ArraySplice) {
+ Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
Object* elms_obj;
{ MaybeObject* maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(receiver);
- if (maybe_elms_obj == NULL) return CallJsBuiltin("ArraySplice", args);
+ EnsureJSArrayWithWritableFastElements(heap, receiver);
+ if (maybe_elms_obj == NULL)
+ return CallJsBuiltin(isolate, "ArraySplice", args);
if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
}
- if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
- return CallJsBuiltin("ArraySplice", args);
+ if (!IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(receiver))) {
+ return CallJsBuiltin(isolate, "ArraySplice", args);
}
FixedArray* elms = FixedArray::cast(elms_obj);
JSArray* array = JSArray::cast(receiver);
@@ -742,7 +761,7 @@
if (arg1->IsSmi()) {
relative_start = Smi::cast(arg1)->value();
} else if (!arg1->IsUndefined()) {
- return CallJsBuiltin("ArraySplice", args);
+ return CallJsBuiltin(isolate, "ArraySplice", args);
}
}
int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
@@ -764,7 +783,7 @@
if (arg2->IsSmi()) {
value = Smi::cast(arg2)->value();
} else {
- return CallJsBuiltin("ArraySplice", args);
+ return CallJsBuiltin(isolate, "ArraySplice", args);
}
}
actual_delete_count = Min(Max(value, 0), len - actual_start);
@@ -773,27 +792,28 @@
JSArray* result_array = NULL;
if (actual_delete_count == 0) {
Object* result;
- { MaybeObject* maybe_result = AllocateEmptyJSArray();
+ { MaybeObject* maybe_result = AllocateEmptyJSArray(heap);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
result_array = JSArray::cast(result);
} else {
// Allocate result array.
Object* result;
- { MaybeObject* maybe_result = AllocateJSArray();
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
result_array = JSArray::cast(result);
{ MaybeObject* maybe_result =
- Heap::AllocateUninitializedFixedArray(actual_delete_count);
+ heap->AllocateUninitializedFixedArray(actual_delete_count);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
FixedArray* result_elms = FixedArray::cast(result);
AssertNoAllocation no_gc;
// Fill newly created array.
- CopyElements(&no_gc,
+ CopyElements(heap,
+ &no_gc,
result_elms, 0,
elms, actual_start,
actual_delete_count);
@@ -811,7 +831,7 @@
if (item_count < actual_delete_count) {
// Shrink the array.
- const bool trim_array = !Heap::lo_space()->Contains(elms) &&
+ const bool trim_array = !heap->lo_space()->Contains(elms) &&
((actual_start + item_count) <
(len - actual_delete_count - actual_start));
if (trim_array) {
@@ -822,15 +842,15 @@
memmove(start + delta, start, actual_start * kPointerSize);
}
- elms = LeftTrimFixedArray(elms, delta);
+ elms = LeftTrimFixedArray(heap, elms, delta);
array->set_elements(elms, SKIP_WRITE_BARRIER);
} else {
AssertNoAllocation no_gc;
- MoveElements(&no_gc,
+ MoveElements(heap, &no_gc,
elms, actual_start + item_count,
elms, actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
- FillWithHoles(elms, new_length, len);
+ FillWithHoles(heap, elms, new_length, len);
}
} else if (item_count > actual_delete_count) {
// Currently fixed arrays cannot grow too big, so
@@ -843,7 +863,7 @@
int capacity = new_length + (new_length >> 1) + 16;
Object* obj;
{ MaybeObject* maybe_obj =
- Heap::AllocateUninitializedFixedArray(capacity);
+ heap->AllocateUninitializedFixedArray(capacity);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
FixedArray* new_elms = FixedArray::cast(obj);
@@ -851,22 +871,22 @@
AssertNoAllocation no_gc;
// Copy the part before actual_start as is.
if (actual_start > 0) {
- CopyElements(&no_gc, new_elms, 0, elms, 0, actual_start);
+ CopyElements(heap, &no_gc, new_elms, 0, elms, 0, actual_start);
}
const int to_copy = len - actual_delete_count - actual_start;
if (to_copy > 0) {
- CopyElements(&no_gc,
+ CopyElements(heap, &no_gc,
new_elms, actual_start + item_count,
elms, actual_start + actual_delete_count,
to_copy);
}
- FillWithHoles(new_elms, new_length, capacity);
+ FillWithHoles(heap, new_elms, new_length, capacity);
elms = new_elms;
array->set_elements(elms);
} else {
AssertNoAllocation no_gc;
- MoveElements(&no_gc,
+ MoveElements(heap, &no_gc,
elms, actual_start + item_count,
elms, actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
@@ -887,11 +907,12 @@
BUILTIN(ArrayConcat) {
- Context* global_context = Top::context()->global_context();
+ Heap* heap = isolate->heap();
+ Context* global_context = isolate->context()->global_context();
JSObject* array_proto =
JSObject::cast(global_context->array_function()->prototype());
- if (!ArrayPrototypeHasNoElements(global_context, array_proto)) {
- return CallJsBuiltin("ArrayConcat", args);
+ if (!ArrayPrototypeHasNoElements(heap, global_context, array_proto)) {
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
}
// Iterate through all the arguments performing checks
@@ -902,7 +923,7 @@
Object* arg = args[i];
if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements()
|| JSArray::cast(arg)->GetPrototype() != array_proto) {
- return CallJsBuiltin("ArrayConcat", args);
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
}
int len = Smi::cast(JSArray::cast(arg)->length())->value();
@@ -915,23 +936,23 @@
ASSERT(result_len >= 0);
if (result_len > FixedArray::kMaxLength) {
- return CallJsBuiltin("ArrayConcat", args);
+ return CallJsBuiltin(isolate, "ArrayConcat", args);
}
}
if (result_len == 0) {
- return AllocateEmptyJSArray();
+ return AllocateEmptyJSArray(heap);
}
// Allocate result.
Object* result;
- { MaybeObject* maybe_result = AllocateJSArray();
+ { MaybeObject* maybe_result = AllocateJSArray(heap);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
JSArray* result_array = JSArray::cast(result);
{ MaybeObject* maybe_result =
- Heap::AllocateUninitializedFixedArray(result_len);
+ heap->AllocateUninitializedFixedArray(result_len);
if (!maybe_result->ToObject(&result)) return maybe_result;
}
FixedArray* result_elms = FixedArray::cast(result);
@@ -944,7 +965,7 @@
int len = Smi::cast(array->length())->value();
if (len > 0) {
FixedArray* elms = FixedArray::cast(array->elements());
- CopyElements(&no_gc, result_elms, start_pos, elms, 0, len);
+ CopyElements(heap, &no_gc, result_elms, start_pos, elms, 0, len);
start_pos += len;
}
}
@@ -964,29 +985,29 @@
BUILTIN(StrictArgumentsCallee) {
HandleScope scope;
- return Top::Throw(*Factory::NewTypeError("strict_arguments_callee",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ "strict_arguments_callee", HandleVector<Object>(NULL, 0)));
}
BUILTIN(StrictArgumentsCaller) {
HandleScope scope;
- return Top::Throw(*Factory::NewTypeError("strict_arguments_caller",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ "strict_arguments_caller", HandleVector<Object>(NULL, 0)));
}
BUILTIN(StrictFunctionCaller) {
HandleScope scope;
- return Top::Throw(*Factory::NewTypeError("strict_function_caller",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ "strict_function_caller", HandleVector<Object>(NULL, 0)));
}
BUILTIN(StrictFunctionArguments) {
HandleScope scope;
- return Top::Throw(*Factory::NewTypeError("strict_function_arguments",
- HandleVector<Object>(NULL, 0)));
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ "strict_function_arguments", HandleVector<Object>(NULL, 0)));
}
@@ -1000,7 +1021,8 @@
// overwritten with undefined. Arguments that do fit the expected
// type is overwritten with the object in the prototype chain that
// actually has that type.
-static inline Object* TypeCheck(int argc,
+static inline Object* TypeCheck(Heap* heap,
+ int argc,
Object** argv,
FunctionTemplateInfo* info) {
Object* recv = argv[0];
@@ -1012,12 +1034,12 @@
Object* holder = recv;
if (!recv_type->IsUndefined()) {
- for (; holder != Heap::null_value(); holder = holder->GetPrototype()) {
+ for (; holder != heap->null_value(); holder = holder->GetPrototype()) {
if (holder->IsInstanceOf(FunctionTemplateInfo::cast(recv_type))) {
break;
}
}
- if (holder == Heap::null_value()) return holder;
+ if (holder == heap->null_value()) return holder;
}
Object* args_obj = sig->args();
// If there is no argument signature we're done
@@ -1030,13 +1052,13 @@
if (argtype->IsUndefined()) continue;
Object** arg = &argv[-1 - i];
Object* current = *arg;
- for (; current != Heap::null_value(); current = current->GetPrototype()) {
+ for (; current != heap->null_value(); current = current->GetPrototype()) {
if (current->IsInstanceOf(FunctionTemplateInfo::cast(argtype))) {
*arg = current;
break;
}
}
- if (current == Heap::null_value()) *arg = Heap::undefined_value();
+ if (current == heap->null_value()) *arg = heap->undefined_value();
}
return holder;
}
@@ -1044,31 +1066,33 @@
template <bool is_construct>
MUST_USE_RESULT static MaybeObject* HandleApiCallHelper(
- BuiltinArguments<NEEDS_CALLED_FUNCTION> args) {
- ASSERT(is_construct == CalledAsConstructor());
+ BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
+ ASSERT(is_construct == CalledAsConstructor(isolate));
+ Heap* heap = isolate->heap();
- HandleScope scope;
+ HandleScope scope(isolate);
Handle<JSFunction> function = args.called_function();
ASSERT(function->shared()->IsApiFunction());
FunctionTemplateInfo* fun_data = function->shared()->get_api_func_data();
if (is_construct) {
- Handle<FunctionTemplateInfo> desc(fun_data);
+ Handle<FunctionTemplateInfo> desc(fun_data, isolate);
bool pending_exception = false;
- Factory::ConfigureInstance(desc, Handle<JSObject>::cast(args.receiver()),
- &pending_exception);
- ASSERT(Top::has_pending_exception() == pending_exception);
+ isolate->factory()->ConfigureInstance(
+ desc, Handle<JSObject>::cast(args.receiver()), &pending_exception);
+ ASSERT(isolate->has_pending_exception() == pending_exception);
if (pending_exception) return Failure::Exception();
fun_data = *desc;
}
- Object* raw_holder = TypeCheck(args.length(), &args[0], fun_data);
+ Object* raw_holder = TypeCheck(heap, args.length(), &args[0], fun_data);
if (raw_holder->IsNull()) {
// This function cannot be called with the given receiver. Abort!
Handle<Object> obj =
- Factory::NewTypeError("illegal_invocation", HandleVector(&function, 1));
- return Top::Throw(*obj);
+ isolate->factory()->NewTypeError(
+ "illegal_invocation", HandleVector(&function, 1));
+ return isolate->Throw(*obj);
}
Object* raw_call_data = fun_data->call_code();
@@ -1080,10 +1104,10 @@
Object* data_obj = call_data->data();
Object* result;
- LOG(ApiObjectAccess("call", JSObject::cast(*args.receiver())));
+ LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
ASSERT(raw_holder->IsJSObject());
- CustomArguments custom;
+ CustomArguments custom(isolate);
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
data_obj, *function, raw_holder);
@@ -1096,17 +1120,18 @@
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.
- VMState state(EXTERNAL);
- ExternalCallbackScope call_scope(v8::ToCData<Address>(callback_obj));
+ VMState state(isolate, EXTERNAL);
+ ExternalCallbackScope call_scope(isolate,
+ v8::ToCData<Address>(callback_obj));
value = callback(new_args);
}
if (value.IsEmpty()) {
- result = Heap::undefined_value();
+ result = heap->undefined_value();
} else {
result = *reinterpret_cast<Object**>(*value);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!is_construct || result->IsJSObject()) return result;
}
@@ -1115,12 +1140,12 @@
BUILTIN(HandleApiCall) {
- return HandleApiCallHelper<false>(args);
+ return HandleApiCallHelper<false>(args, isolate);
}
BUILTIN(HandleApiCallConstruct) {
- return HandleApiCallHelper<true>(args);
+ return HandleApiCallHelper<true>(args, isolate);
}
@@ -1142,7 +1167,8 @@
BUILTIN(FastHandleApiCall) {
- ASSERT(!CalledAsConstructor());
+ ASSERT(!CalledAsConstructor(isolate));
+ Heap* heap = isolate->heap();
const bool is_construct = false;
// We expect four more arguments: callback, function, call data, and holder.
@@ -1161,25 +1187,26 @@
VerifyTypeCheck(Utils::OpenHandle(*new_args.Holder()),
Utils::OpenHandle(*new_args.Callee()));
#endif
- HandleScope scope;
+ HandleScope scope(isolate);
Object* result;
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.
- VMState state(EXTERNAL);
- ExternalCallbackScope call_scope(v8::ToCData<Address>(callback_obj));
+ VMState state(isolate, EXTERNAL);
+ ExternalCallbackScope call_scope(isolate,
+ v8::ToCData<Address>(callback_obj));
v8::InvocationCallback callback =
v8::ToCData<v8::InvocationCallback>(callback_obj);
value = callback(new_args);
}
if (value.IsEmpty()) {
- result = Heap::undefined_value();
+ result = heap->undefined_value();
} else {
result = *reinterpret_cast<Object**>(*value);
}
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
@@ -1188,11 +1215,13 @@
// API. The object can be called as either a constructor (using new) or just as
// a function (without new).
MUST_USE_RESULT static MaybeObject* HandleApiCallAsFunctionOrConstructor(
+ Isolate* isolate,
bool is_construct_call,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
// Non-functions are never called as constructors. Even if this is an object
// called as a constructor the delegate call is not a construct call.
- ASSERT(!CalledAsConstructor());
+ ASSERT(!CalledAsConstructor(isolate));
+ Heap* heap = isolate->heap();
Handle<Object> receiver = args.at<Object>(0);
@@ -1215,11 +1244,10 @@
// Get the data for the call and perform the callback.
Object* result;
{
- HandleScope scope;
+ HandleScope scope(isolate);
+ LOG(isolate, ApiObjectAccess("call non-function", obj));
- LOG(ApiObjectAccess("call non-function", obj));
-
- CustomArguments custom;
+ CustomArguments custom(isolate);
v8::ImplementationUtilities::PrepareArgumentsData(custom.end(),
call_data->data(), constructor, obj);
v8::Arguments new_args = v8::ImplementationUtilities::NewArguments(
@@ -1230,18 +1258,19 @@
v8::Handle<v8::Value> value;
{
// Leaving JavaScript.
- VMState state(EXTERNAL);
- ExternalCallbackScope call_scope(v8::ToCData<Address>(callback_obj));
+ VMState state(isolate, EXTERNAL);
+ ExternalCallbackScope call_scope(isolate,
+ v8::ToCData<Address>(callback_obj));
value = callback(new_args);
}
if (value.IsEmpty()) {
- result = Heap::undefined_value();
+ result = heap->undefined_value();
} else {
result = *reinterpret_cast<Object**>(*value);
}
}
// Check for exceptions and return result.
- RETURN_IF_SCHEDULED_EXCEPTION();
+ RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return result;
}
@@ -1249,14 +1278,14 @@
// Handle calls to non-function objects created through the API. This delegate
// function is used when the call is a normal function call.
BUILTIN(HandleApiCallAsFunction) {
- return HandleApiCallAsFunctionOrConstructor(false, args);
+ return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
}
// Handle calls to non-function objects created through the API. This delegate
// function is used when the call is a construct call.
BUILTIN(HandleApiCallAsConstructor) {
- return HandleApiCallAsFunctionOrConstructor(true, args);
+ return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
}
@@ -1465,74 +1494,113 @@
}
#endif
-Object* Builtins::builtins_[builtin_count] = { NULL, };
-const char* Builtins::names_[builtin_count] = { NULL, };
+Builtins::Builtins() : initialized_(false) {
+ memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
+ memset(names_, 0, sizeof(names_[0]) * builtin_count);
+}
+
+
+Builtins::~Builtins() {
+}
+
+
#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
- Address Builtins::c_functions_[cfunction_count] = {
- BUILTIN_LIST_C(DEF_ENUM_C)
- };
+Address const Builtins::c_functions_[cfunction_count] = {
+ BUILTIN_LIST_C(DEF_ENUM_C)
+};
#undef DEF_ENUM_C
#define DEF_JS_NAME(name, ignore) #name,
#define DEF_JS_ARGC(ignore, argc) argc,
-const char* Builtins::javascript_names_[id_count] = {
+const char* const Builtins::javascript_names_[id_count] = {
BUILTINS_LIST_JS(DEF_JS_NAME)
};
-int Builtins::javascript_argc_[id_count] = {
+int const Builtins::javascript_argc_[id_count] = {
BUILTINS_LIST_JS(DEF_JS_ARGC)
};
#undef DEF_JS_NAME
#undef DEF_JS_ARGC
-static bool is_initialized = false;
-void Builtins::Setup(bool create_heap_objects) {
- ASSERT(!is_initialized);
+struct BuiltinDesc {
+ byte* generator;
+ byte* c_code;
+ const char* s_name; // name is only used for generating log information.
+ int name;
+ Code::Flags flags;
+ BuiltinExtraArguments extra_args;
+};
- // Create a scope for the handles in the builtins.
- HandleScope scope;
+class BuiltinFunctionTable {
+ public:
+ BuiltinFunctionTable() {
+ Builtins::InitBuiltinFunctionTable();
+ }
- struct BuiltinDesc {
- byte* generator;
- byte* c_code;
- const char* s_name; // name is only used for generating log information.
- int name;
- Code::Flags flags;
- BuiltinExtraArguments extra_args;
- };
+ static const BuiltinDesc* functions() { return functions_; }
-#define DEF_FUNCTION_PTR_C(name, extra_args) \
- { FUNCTION_ADDR(Generate_Adaptor), \
- FUNCTION_ADDR(Builtin_##name), \
- #name, \
- c_##name, \
- Code::ComputeFlags(Code::BUILTIN), \
- extra_args \
- },
+ private:
+ static BuiltinDesc functions_[Builtins::builtin_count + 1];
-#define DEF_FUNCTION_PTR_A(name, kind, state, extra) \
- { FUNCTION_ADDR(Generate_##name), \
- NULL, \
- #name, \
- name, \
- Code::ComputeFlags(Code::kind, NOT_IN_LOOP, state, extra), \
- NO_EXTRA_ARGUMENTS \
- },
+ friend class Builtins;
+};
- // Define array of pointers to generators and C builtin functions.
- static BuiltinDesc functions[] = {
- BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
- BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
- BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
- // Terminator:
- { NULL, NULL, NULL, builtin_count, static_cast<Code::Flags>(0),
- NO_EXTRA_ARGUMENTS }
- };
+BuiltinDesc BuiltinFunctionTable::functions_[Builtins::builtin_count + 1];
+static const BuiltinFunctionTable builtin_function_table_init;
+
+// Define array of pointers to generators and C builtin functions.
+// We do this in a sort of roundabout way so that we can do the initialization
+// within the lexical scope of Builtins:: and within a context where
+// Code::Flags names a non-abstract type.
+void Builtins::InitBuiltinFunctionTable() {
+ BuiltinDesc* functions = BuiltinFunctionTable::functions_;
+ functions[builtin_count].generator = NULL;
+ functions[builtin_count].c_code = NULL;
+ functions[builtin_count].s_name = NULL;
+ functions[builtin_count].name = builtin_count;
+ functions[builtin_count].flags = static_cast<Code::Flags>(0);
+ functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;
+
+#define DEF_FUNCTION_PTR_C(aname, aextra_args) \
+ functions->generator = FUNCTION_ADDR(Generate_Adaptor); \
+ functions->c_code = FUNCTION_ADDR(Builtin_##aname); \
+ functions->s_name = #aname; \
+ functions->name = c_##aname; \
+ functions->flags = Code::ComputeFlags(Code::BUILTIN); \
+ functions->extra_args = aextra_args; \
+ ++functions;
+
+#define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \
+ functions->generator = FUNCTION_ADDR(Generate_##aname); \
+ functions->c_code = NULL; \
+ functions->s_name = #aname; \
+ functions->name = aname; \
+ functions->flags = Code::ComputeFlags(Code::kind, \
+ NOT_IN_LOOP, \
+ state, \
+ extra); \
+ functions->extra_args = NO_EXTRA_ARGUMENTS; \
+ ++functions;
+
+ BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
+ BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
+ BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
+
#undef DEF_FUNCTION_PTR_C
#undef DEF_FUNCTION_PTR_A
+}
+void Builtins::Setup(bool create_heap_objects) {
+ ASSERT(!initialized_);
+ Heap* heap = Isolate::Current()->heap();
+
+ // Create a scope for the handles in the builtins.
+ HandleScope scope;
+
+ const BuiltinDesc* functions = BuiltinFunctionTable::functions();
+
// For now we generate builtin adaptor code into a stack-allocated
// buffer, before copying it into individual code objects.
byte buffer[4*KB];
@@ -1559,14 +1627,15 @@
// This simplifies things because we don't need to retry.
AlwaysAllocateScope __scope__;
{ MaybeObject* maybe_code =
- Heap::CreateCode(desc, flags, masm.CodeObject());
+ heap->CreateCode(desc, flags, masm.CodeObject());
if (!maybe_code->ToObject(&code)) {
v8::internal::V8::FatalProcessOutOfMemory("CreateCode");
}
}
}
// Log the event and add the code to the builtins array.
- PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG,
+ PROFILE(ISOLATE,
+ CodeCreateEvent(Logger::BUILTIN_TAG,
Code::cast(code),
functions[i].s_name));
GDBJIT(AddCode(GDBJITInterface::BUILTIN,
@@ -1588,12 +1657,12 @@
}
// Mark as initialized.
- is_initialized = true;
+ initialized_ = true;
}
void Builtins::TearDown() {
- is_initialized = false;
+ initialized_ = false;
}
@@ -1603,7 +1672,8 @@
const char* Builtins::Lookup(byte* pc) {
- if (is_initialized) { // may be called during initialization (disassembler!)
+ // may be called during initialization (disassembler!)
+ if (initialized_) {
for (int i = 0; i < builtin_count; i++) {
Code* entry = Code::cast(builtins_[i]);
if (entry->contains(pc)) {
« no previous file with comments | « src/builtins.h ('k') | src/checks.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698