summaryrefslogtreecommitdiffstats
path: root/V8Binding/v8/src/runtime.cc
diff options
context:
space:
mode:
Diffstat (limited to 'V8Binding/v8/src/runtime.cc')
-rw-r--r--V8Binding/v8/src/runtime.cc160
1 files changed, 101 insertions, 59 deletions
diff --git a/V8Binding/v8/src/runtime.cc b/V8Binding/v8/src/runtime.cc
index 350d391..56e9f85 100644
--- a/V8Binding/v8/src/runtime.cc
+++ b/V8Binding/v8/src/runtime.cc
@@ -155,33 +155,43 @@ static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
}
// Deep copy local elements.
- if (copy->HasFastElements()) {
- FixedArray* elements = copy->elements();
- WriteBarrierMode mode = elements->GetWriteBarrierMode();
- for (int i = 0; i < elements->length(); i++) {
- Object* value = elements->get(i);
- if (value->IsJSObject()) {
- JSObject* jsObject = JSObject::cast(value);
- result = DeepCopyBoilerplate(jsObject);
- if (result->IsFailure()) return result;
- elements->set(i, result, mode);
- }
- }
- } else {
- NumberDictionary* element_dictionary = copy->element_dictionary();
- int capacity = element_dictionary->Capacity();
- for (int i = 0; i < capacity; i++) {
- Object* k = element_dictionary->KeyAt(i);
- if (element_dictionary->IsKey(k)) {
- Object* value = element_dictionary->ValueAt(i);
+ // Pixel elements cannot be created using an object literal.
+ ASSERT(!copy->HasPixelElements());
+ switch (copy->GetElementsKind()) {
+ case JSObject::FAST_ELEMENTS: {
+ FixedArray* elements = FixedArray::cast(copy->elements());
+ WriteBarrierMode mode = elements->GetWriteBarrierMode();
+ for (int i = 0; i < elements->length(); i++) {
+ Object* value = elements->get(i);
if (value->IsJSObject()) {
JSObject* jsObject = JSObject::cast(value);
result = DeepCopyBoilerplate(jsObject);
if (result->IsFailure()) return result;
- element_dictionary->ValueAtPut(i, result);
+ elements->set(i, result, mode);
}
}
+ break;
}
+ case JSObject::DICTIONARY_ELEMENTS: {
+ NumberDictionary* element_dictionary = copy->element_dictionary();
+ int capacity = element_dictionary->Capacity();
+ for (int i = 0; i < capacity; i++) {
+ Object* k = element_dictionary->KeyAt(i);
+ if (element_dictionary->IsKey(k)) {
+ Object* value = element_dictionary->ValueAt(i);
+ if (value->IsJSObject()) {
+ JSObject* jsObject = JSObject::cast(value);
+ result = DeepCopyBoilerplate(jsObject);
+ if (result->IsFailure()) return result;
+ element_dictionary->ValueAtPut(i, result);
+ }
+ }
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ break;
}
return copy;
}
@@ -258,6 +268,7 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
{ // Add the constant properties to the boilerplate.
int length = constant_properties->length();
OptimizedObjectForAddingMultipleProperties opt(boilerplate,
+ length / 2,
!is_result_from_cache);
for (int index = 0; index < length; index +=2) {
Handle<Object> key(constant_properties->get(index+0));
@@ -1637,7 +1648,7 @@ void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
}
case SUBJECT_CAPTURE: {
int capture = part.data;
- FixedArray* match_info = last_match_info->elements();
+ FixedArray* match_info = FixedArray::cast(last_match_info->elements());
int from = RegExpImpl::GetCapture(match_info, capture * 2);
int to = RegExpImpl::GetCapture(match_info, capture * 2 + 1);
if (from >= 0 && to > from) {
@@ -1717,7 +1728,8 @@ static Object* StringReplaceRegExpWithString(String* subject,
int start, end;
{
AssertNoAllocation match_info_array_is_not_in_a_handle;
- FixedArray* match_info_array = last_match_info_handle->elements();
+ FixedArray* match_info_array =
+ FixedArray::cast(last_match_info_handle->elements());
ASSERT_EQ(capture_count * 2 + 2,
RegExpImpl::GetLastCaptureCount(match_info_array));
@@ -2345,7 +2357,7 @@ static Object* Runtime_StringMatch(Arguments args) {
int end;
{
AssertNoAllocation no_alloc;
- FixedArray* elements = regexp_info->elements();
+ FixedArray* elements = FixedArray::cast(regexp_info->elements());
start = Smi::cast(elements->get(RegExpImpl::kFirstCapture))->value();
end = Smi::cast(elements->get(RegExpImpl::kFirstCapture + 1))->value();
}
@@ -3022,7 +3034,7 @@ static Object* Runtime_ToSlowProperties(Arguments args) {
Handle<Object> object = args.at<Object>(0);
if (object->IsJSObject()) {
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
- js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
+ js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
}
return *object;
}
@@ -4885,7 +4897,7 @@ static Object* Runtime_DateParseString(Arguments args) {
AssertNoAllocation no_allocation;
- FixedArray* output_array = output->elements();
+ FixedArray* output_array = FixedArray::cast(output->elements());
RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
bool result;
if (str->IsAsciiRepresentation()) {
@@ -4908,7 +4920,7 @@ static Object* Runtime_DateLocalTimezone(Arguments args) {
ASSERT(args.length() == 1);
CONVERT_DOUBLE_CHECKED(x, args[0]);
- char* zone = OS::LocalTimezone(x);
+ const char* zone = OS::LocalTimezone(x);
return Heap::AllocateStringFromUtf8(CStrVector(zone));
}
@@ -5173,37 +5185,62 @@ static uint32_t IterateElements(Handle<JSObject> receiver,
ArrayConcatVisitor* visitor) {
uint32_t num_of_elements = 0;
- if (receiver->HasFastElements()) {
- Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
- uint32_t len = elements->length();
- if (range < len) len = range;
+ switch (receiver->GetElementsKind()) {
+ case JSObject::FAST_ELEMENTS: {
+ Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
+ uint32_t len = elements->length();
+ if (range < len) {
+ len = range;
+ }
- for (uint32_t j = 0; j < len; j++) {
- Handle<Object> e(elements->get(j));
- if (!e->IsTheHole()) {
+ for (uint32_t j = 0; j < len; j++) {
+ Handle<Object> e(elements->get(j));
+ if (!e->IsTheHole()) {
+ num_of_elements++;
+ if (visitor) {
+ visitor->visit(j, e);
+ }
+ }
+ }
+ break;
+ }
+ case JSObject::PIXEL_ELEMENTS: {
+ Handle<PixelArray> pixels(PixelArray::cast(receiver->elements()));
+ uint32_t len = pixels->length();
+ if (range < len) {
+ len = range;
+ }
+
+ for (uint32_t j = 0; j < len; j++) {
num_of_elements++;
- if (visitor)
+ if (visitor != NULL) {
+ Handle<Smi> e(Smi::FromInt(pixels->get(j)));
visitor->visit(j, e);
+ }
}
+ break;
}
-
- } else {
- Handle<NumberDictionary> dict(receiver->element_dictionary());
- uint32_t capacity = dict->Capacity();
- for (uint32_t j = 0; j < capacity; j++) {
- Handle<Object> k(dict->KeyAt(j));
- if (dict->IsKey(*k)) {
- ASSERT(k->IsNumber());
- uint32_t index = static_cast<uint32_t>(k->Number());
- if (index < range) {
- num_of_elements++;
- if (visitor) {
- visitor->visit(index,
- Handle<Object>(dict->ValueAt(j)));
+ case JSObject::DICTIONARY_ELEMENTS: {
+ Handle<NumberDictionary> dict(receiver->element_dictionary());
+ uint32_t capacity = dict->Capacity();
+ for (uint32_t j = 0; j < capacity; j++) {
+ Handle<Object> k(dict->KeyAt(j));
+ if (dict->IsKey(*k)) {
+ ASSERT(k->IsNumber());
+ uint32_t index = static_cast<uint32_t>(k->Number());
+ if (index < range) {
+ num_of_elements++;
+ if (visitor) {
+ visitor->visit(index, Handle<Object>(dict->ValueAt(j)));
+ }
}
}
}
+ break;
}
+ default:
+ UNREACHABLE();
+ break;
}
return num_of_elements;
@@ -7408,14 +7445,15 @@ static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
// Not sure when this can happen but skip it just in case.
if (!raw_fun->IsJSFunction())
return false;
- if ((raw_fun == caller) && !(*seen_caller) && frame->IsConstructor()) {
+ if ((raw_fun == caller) && !(*seen_caller)) {
*seen_caller = true;
return false;
}
- // Skip the most obvious builtin calls. Some builtin calls (such as
- // Number.ADD which is invoked using 'call') are very difficult to
- // recognize so we're leaving them in for now.
- return !frame->receiver()->IsJSBuiltinsObject();
+ // Skip all frames until we've seen the caller. Also, skip the most
+ // obvious builtin calls. Some builtin calls (such as Number.ADD
+ // which is invoked using 'call') are very difficult to recognize
+ // so we're leaving them in for now.
+ return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
}
@@ -7424,7 +7462,7 @@ static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
// code offset.
static Object* Runtime_CollectStackTrace(Arguments args) {
ASSERT_EQ(args.length(), 2);
- Object* caller = args[0];
+ Handle<Object> caller = args.at<Object>(0);
CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]);
HandleScope scope;
@@ -7433,12 +7471,14 @@ static Object* Runtime_CollectStackTrace(Arguments args) {
Handle<JSArray> result = Factory::NewJSArray(initial_size * 3);
StackFrameIterator iter;
- bool seen_caller = false;
+ // If the caller parameter is a function we skip frames until we're
+ // under it before starting to collect.
+ bool seen_caller = !caller->IsJSFunction();
int cursor = 0;
int frames_seen = 0;
while (!iter.done() && frames_seen < limit) {
StackFrame* raw_frame = iter.frame();
- if (ShowFrameInStackTrace(raw_frame, caller, &seen_caller)) {
+ if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) {
frames_seen++;
JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
Object* recv = frame->receiver();
@@ -7446,15 +7486,17 @@ static Object* Runtime_CollectStackTrace(Arguments args) {
Address pc = frame->pc();
Address start = frame->code()->address();
Smi* offset = Smi::FromInt(pc - start);
- FixedArray* elements = result->elements();
+ FixedArray* elements = FixedArray::cast(result->elements());
if (cursor + 2 < elements->length()) {
elements->set(cursor++, recv);
elements->set(cursor++, fun);
elements->set(cursor++, offset, SKIP_WRITE_BARRIER);
} else {
HandleScope scope;
- SetElement(result, cursor++, Handle<Object>(recv));
- SetElement(result, cursor++, Handle<Object>(fun));
+ Handle<Object> recv_handle(recv);
+ Handle<Object> fun_handle(fun);
+ SetElement(result, cursor++, recv_handle);
+ SetElement(result, cursor++, fun_handle);
SetElement(result, cursor++, Handle<Smi>(offset));
}
}