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

Unified Diff: src/runtime.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 3935)
+++ src/runtime.cc (working copy)
@@ -1208,17 +1208,6 @@
}
-static Object* Runtime_TransformToFastProperties(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, object, 0);
- if (!object->HasFastProperties() && !object->IsGlobalObject()) {
- TransformToFastProperties(object, 0);
- }
- return *object;
-}
-
-
static Object* Runtime_RegExpExec(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 4);
@@ -2287,6 +2276,20 @@
return -1;
}
+
+template <typename schar>
+static int SingleCharLastIndexOf(Vector<const schar> string,
+ schar pattern_char,
+ int start_index) {
+ for (int i = start_index; i >= 0; i--) {
+ if (pattern_char == string[i]) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+
// Trivial string search for shorter strings.
// On return, if "complete" is set to true, the return value is the
// final result of searching for the patter in the subject.
@@ -2363,7 +2366,7 @@
// We have an ASCII haystack and a non-ASCII needle. Check if there
// really is a non-ASCII character in the needle and bail out if there
// is.
- if (sizeof(pchar) > 1 && sizeof(schar) == 1) {
+ if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
for (int i = 0; i < pat.length(); i++) {
uc16 c = pat[i];
if (c > String::kMaxAsciiCharCode) {
@@ -2466,39 +2469,115 @@
}
+template <typename schar, typename pchar>
+static int StringMatchBackwards(Vector<const schar> sub,
+ Vector<const pchar> pat,
+ int idx) {
+ ASSERT(pat.length() >= 1);
+ ASSERT(idx + pat.length() <= sub.length());
+
+ if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
+ for (int i = 0; i < pat.length(); i++) {
+ uc16 c = pat[i];
+ if (c > String::kMaxAsciiCharCode) {
+ return -1;
+ }
+ }
+ }
+
+ pchar pattern_first_char = pat[0];
+ for (int i = idx; i >= 0; i--) {
+ if (sub[i] != pattern_first_char) continue;
+ int j = 1;
+ while (j < pat.length()) {
+ if (pat[j] != sub[i+j]) {
+ break;
+ }
+ j++;
+ }
+ if (j == pat.length()) {
+ return i;
+ }
+ }
+ return -1;
+}
+
static Object* Runtime_StringLastIndexOf(Arguments args) {
- NoHandleAllocation ha;
+ HandleScope scope; // create a new handle scope
ASSERT(args.length() == 3);
- CONVERT_CHECKED(String, sub, args[0]);
- CONVERT_CHECKED(String, pat, args[1]);
+ CONVERT_ARG_CHECKED(String, sub, 0);
+ CONVERT_ARG_CHECKED(String, pat, 1);
+
Object* index = args[2];
-
- sub->TryFlattenIfNotFlat();
- pat->TryFlattenIfNotFlat();
-
uint32_t start_index;
if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1);
- uint32_t pattern_length = pat->length();
+ uint32_t pat_length = pat->length();
uint32_t sub_length = sub->length();
- if (start_index + pattern_length > sub_length) {
- start_index = sub_length - pattern_length;
+ if (start_index + pat_length > sub_length) {
+ start_index = sub_length - pat_length;
}
- for (int i = start_index; i >= 0; i--) {
- bool found = true;
- for (uint32_t j = 0; j < pattern_length; j++) {
- if (sub->Get(i + j) != pat->Get(j)) {
- found = false;
- break;
+ if (pat_length == 0) {
+ return Smi::FromInt(start_index);
+ }
+
+ if (!sub->IsFlat()) {
+ FlattenString(sub);
+ }
+
+ if (pat_length == 1) {
+ AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
+ if (sub->IsAsciiRepresentation()) {
+ uc16 pchar = pat->Get(0);
+ if (pchar > String::kMaxAsciiCharCode) {
+ return Smi::FromInt(-1);
}
+ return Smi::FromInt(SingleCharLastIndexOf(sub->ToAsciiVector(),
+ static_cast<char>(pat->Get(0)),
+ start_index));
+ } else {
+ return Smi::FromInt(SingleCharLastIndexOf(sub->ToUC16Vector(),
+ pat->Get(0),
+ start_index));
}
- if (found) return Smi::FromInt(i);
}
- return Smi::FromInt(-1);
+ if (!pat->IsFlat()) {
+ FlattenString(pat);
+ }
+
+ AssertNoAllocation no_heap_allocation; // ensure vectors stay valid
+
+ int position = -1;
+
+ if (pat->IsAsciiRepresentation()) {
+ Vector<const char> pat_vector = pat->ToAsciiVector();
+ if (sub->IsAsciiRepresentation()) {
+ position = StringMatchBackwards(sub->ToAsciiVector(),
+ pat_vector,
+ start_index);
+ } else {
+ position = StringMatchBackwards(sub->ToUC16Vector(),
+ pat_vector,
+ start_index);
+ }
+ } else {
+ Vector<const uc16> pat_vector = pat->ToUC16Vector();
+ if (sub->IsAsciiRepresentation()) {
+ position = StringMatchBackwards(sub->ToAsciiVector(),
+ pat_vector,
+ start_index);
+ } else {
+ position = StringMatchBackwards(sub->ToUC16Vector(),
+ pat_vector,
+ start_index);
+ }
+ }
+
+ return Smi::FromInt(position);
}
@@ -2906,7 +2985,7 @@
// If an existing property is either FIELD, NORMAL or CONSTANT_FUNCTION
// delete it to avoid running into trouble in DefineAccessor, which
// handles this incorrectly if the property is readonly (does nothing)
- if (result.IsValid() &&
+ if (result.IsProperty() &&
(result.type() == FIELD || result.type() == NORMAL
|| result.type() == CONSTANT_FUNCTION)) {
obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
@@ -2937,12 +3016,14 @@
// correctly in the case where a property is a field and is reset with
// new attributes.
if (result.IsProperty() && attr != result.GetAttributes()) {
- PropertyDetails details = PropertyDetails(attr, NORMAL);
// New attributes - normalize to avoid writing to instance descriptor
- js_object->NormalizeProperties(KEEP_INOBJECT_PROPERTIES, 0);
- return js_object->SetNormalizedProperty(*name, *obj_value, details);
+ js_object->NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
+ // Use IgnoreAttributes version since a readonly property may be
+ // overridden and SetProperty does not allow this.
+ return js_object->IgnoreAttributesAndSetLocalProperty(*name,
+ *obj_value,
+ attr);
}
-
return Runtime::SetObjectProperty(js_object, name, obj_value, attr);
}
@@ -2969,8 +3050,6 @@
// Check if the given key is an array index.
uint32_t index;
if (Array::IndexFromObject(*key, &index)) {
- ASSERT(attr == NONE);
-
// In Firefox/SpiderMonkey, Safari and Opera you can access the characters
// of a string using [] notation. We need to support this too in
// JavaScript.
@@ -2990,7 +3069,6 @@
if (key->IsString()) {
Handle<Object> result;
if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
- ASSERT(attr == NONE);
result = SetElement(js_object, index, value);
} else {
Handle<String> key_string = Handle<String>::cast(key);
@@ -3008,7 +3086,6 @@
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- ASSERT(attr == NONE);
return js_object->SetElement(index, *value);
} else {
return js_object->SetProperty(*name, *value, attr);
@@ -3025,8 +3102,6 @@
// Check if the given key is an array index.
uint32_t index;
if (Array::IndexFromObject(*key, &index)) {
- ASSERT(attr == NONE);
-
// In Firefox/SpiderMonkey, Safari and Opera you can access the characters
// of a string using [] notation. We need to support this too in
// JavaScript.
@@ -3043,7 +3118,6 @@
if (key->IsString()) {
if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
- ASSERT(attr == NONE);
return js_object->SetElement(index, *value);
} else {
Handle<String> key_string = Handle<String>::cast(key);
@@ -3061,7 +3135,6 @@
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
- ASSERT(attr == NONE);
return js_object->SetElement(index, *value);
} else {
return js_object->IgnoreAttributesAndSetLocalProperty(*name, *value, attr);
@@ -3520,17 +3593,23 @@
static Object* Runtime_ToFastProperties(Arguments args) {
+ HandleScope scope;
+
ASSERT(args.length() == 1);
Handle<Object> object = args.at<Object>(0);
if (object->IsJSObject()) {
Handle<JSObject> js_object = Handle<JSObject>::cast(object);
- js_object->TransformToFastProperties(0);
+ if (!js_object->HasFastProperties() && !js_object->IsGlobalObject()) {
+ js_object->TransformToFastProperties(0);
+ }
}
return *object;
}
static Object* Runtime_ToSlowProperties(Arguments args) {
+ HandleScope scope;
+
ASSERT(args.length() == 1);
Handle<Object> object = args.at<Object>(0);
if (object->IsJSObject()) {
@@ -4559,6 +4638,7 @@
static Object* Runtime_Math_abs(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_abs.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return Heap::AllocateHeapNumber(fabs(x));
@@ -4568,6 +4648,7 @@
static Object* Runtime_Math_acos(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_acos.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::ACOS, x);
@@ -4577,6 +4658,7 @@
static Object* Runtime_Math_asin(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_asin.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::ASIN, x);
@@ -4586,6 +4668,7 @@
static Object* Runtime_Math_atan(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_atan.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::ATAN, x);
@@ -4595,6 +4678,7 @@
static Object* Runtime_Math_atan2(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
+ Counters::math_atan2.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
CONVERT_DOUBLE_CHECKED(y, args[1]);
@@ -4618,6 +4702,7 @@
static Object* Runtime_Math_ceil(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_ceil.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return Heap::NumberFromDouble(ceiling(x));
@@ -4627,6 +4712,7 @@
static Object* Runtime_Math_cos(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_cos.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::COS, x);
@@ -4636,6 +4722,7 @@
static Object* Runtime_Math_exp(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_exp.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::EXP, x);
@@ -4645,6 +4732,7 @@
static Object* Runtime_Math_floor(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_floor.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return Heap::NumberFromDouble(floor(x));
@@ -4654,6 +4742,7 @@
static Object* Runtime_Math_log(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_log.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::LOG, x);
@@ -4694,6 +4783,7 @@
static Object* Runtime_Math_pow(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
+ Counters::math_pow.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
@@ -4732,6 +4822,7 @@
static Object* Runtime_Math_round(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_round.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
if (signbit(x) && x >= -0.5) return Heap::minus_zero_value();
@@ -4744,6 +4835,7 @@
static Object* Runtime_Math_sin(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_sin.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::SIN, x);
@@ -4753,6 +4845,7 @@
static Object* Runtime_Math_sqrt(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_sqrt.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return Heap::AllocateHeapNumber(sqrt(x));
@@ -4762,47 +4855,13 @@
static Object* Runtime_Math_tan(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
+ Counters::math_tan.Increment();
CONVERT_DOUBLE_CHECKED(x, args[0]);
return TranscendentalCache::Get(TranscendentalCache::TAN, x);
}
-// The NewArguments function is only used when constructing the
-// arguments array when calling non-functions from JavaScript in
-// runtime.js:CALL_NON_FUNCTION.
-static Object* Runtime_NewArguments(Arguments args) {
- NoHandleAllocation ha;
- ASSERT(args.length() == 1);
-
- // ECMA-262, 3rd., 10.1.8, p.39
- CONVERT_CHECKED(JSFunction, callee, args[0]);
-
- // Compute the frame holding the arguments.
- JavaScriptFrameIterator it;
- it.AdvanceToArgumentsFrame();
- JavaScriptFrame* frame = it.frame();
-
- const int length = frame->GetProvidedParametersCount();
- Object* result = Heap::AllocateArgumentsObject(callee, length);
- if (result->IsFailure()) return result;
- if (length > 0) {
- Object* obj = Heap::AllocateFixedArray(length);
- if (obj->IsFailure()) return obj;
- FixedArray* array = FixedArray::cast(obj);
- ASSERT(array->length() == length);
-
- AssertNoAllocation no_gc;
- WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
- for (int i = 0; i < length; i++) {
- array->set(i, frame->GetParameter(i), mode);
- }
- JSObject::cast(result)->set_elements(array);
- }
- return result;
-}
-
-
static Object* Runtime_NewArgumentsFast(Arguments args) {
NoHandleAllocation ha;
ASSERT(args.length() == 3);
@@ -4849,21 +4908,21 @@
}
-static Code* ComputeConstructStub(Handle<SharedFunctionInfo> shared) {
- // TODO(385): Change this to create a construct stub specialized for
- // the given map to make allocation of simple objects - and maybe
- // arrays - much faster.
- if (FLAG_inline_new
- && shared->has_only_simple_this_property_assignments()) {
+static Code* ComputeConstructStub(Handle<JSFunction> function) {
+ Handle<Object> prototype = Factory::null_value();
+ if (function->has_instance_prototype()) {
+ prototype = Handle<Object>(function->instance_prototype());
+ }
+ if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
ConstructStubCompiler compiler;
- Object* code = compiler.CompileConstructStub(*shared);
+ Object* code = compiler.CompileConstructStub(function->shared());
if (code->IsFailure()) {
return Builtins::builtin(Builtins::JSConstructStubGeneric);
}
return Code::cast(code);
}
- return shared->construct_stub();
+ return function->shared()->construct_stub();
}
@@ -4913,10 +4972,9 @@
bool first_allocation = !function->has_initial_map();
Handle<JSObject> result = Factory::NewJSObject(function);
if (first_allocation) {
- Handle<Map> map = Handle<Map>(function->initial_map());
Handle<Code> stub = Handle<Code>(
- ComputeConstructStub(Handle<SharedFunctionInfo>(function->shared())));
- function->shared()->set_construct_stub(*stub);
+ ComputeConstructStub(Handle<JSFunction>(function)));
+ shared->set_construct_stub(*stub);
}
Counters::constructed_objects.Increment();
@@ -4955,28 +5013,6 @@
}
-static Object* Runtime_GetCalledFunction(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 0);
- StackFrameIterator it;
- // Get past the JS-to-C exit frame.
- ASSERT(it.frame()->is_exit());
- it.Advance();
- // Get past the CALL_NON_FUNCTION activation frame.
- ASSERT(it.frame()->is_java_script());
- it.Advance();
- // Argument adaptor frames do not copy the function; we have to skip
- // past them to get to the real calling frame.
- if (it.frame()->is_arguments_adaptor()) it.Advance();
- // Get the function from the top of the expression stack of the
- // calling frame.
- StandardFrame* frame = StandardFrame::cast(it.frame());
- int index = frame->ComputeExpressionsCount() - 1;
- Object* result = frame->GetExpression(index);
- return result;
-}
-
-
static Object* Runtime_GetFunctionDelegate(Arguments args) {
HandleScope scope;
ASSERT(args.length() == 1);
@@ -7981,20 +8017,22 @@
static Object* Runtime_ProfilerResume(Arguments args) {
NoHandleAllocation ha;
- ASSERT(args.length() == 1);
+ ASSERT(args.length() == 2);
CONVERT_CHECKED(Smi, smi_modules, args[0]);
- v8::V8::ResumeProfilerEx(smi_modules->value());
+ CONVERT_CHECKED(Smi, smi_tag, args[1]);
+ v8::V8::ResumeProfilerEx(smi_modules->value(), smi_tag->value());
return Heap::undefined_value();
}
static Object* Runtime_ProfilerPause(Arguments args) {
NoHandleAllocation ha;
- ASSERT(args.length() == 1);
+ ASSERT(args.length() == 2);
CONVERT_CHECKED(Smi, smi_modules, args[0]);
- v8::V8::PauseProfilerEx(smi_modules->value());
+ CONVERT_CHECKED(Smi, smi_tag, args[1]);
+ v8::V8::PauseProfilerEx(smi_modules->value(), smi_tag->value());
return Heap::undefined_value();
}
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698