diff options
Diffstat (limited to 'V8Binding/v8/src/runtime.cc')
-rw-r--r-- | V8Binding/v8/src/runtime.cc | 160 |
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)); } } |