OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 2503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2514 ASSERT(args.length() == 2); | 2514 ASSERT(args.length() == 2); |
2515 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); | 2515 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); |
2516 CONVERT_SMI_ARG_CHECKED(properties, 1); | 2516 CONVERT_SMI_ARG_CHECKED(properties, 1); |
2517 if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { | 2517 if (object->HasFastProperties() && !object->IsJSGlobalProxy()) { |
2518 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); | 2518 JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); |
2519 } | 2519 } |
2520 return *object; | 2520 return *object; |
2521 } | 2521 } |
2522 | 2522 |
2523 | 2523 |
2524 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { | 2524 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecInternal) { |
2525 HandleScope scope(isolate); | 2525 HandleScope scope(isolate); |
2526 ASSERT(args.length() == 4); | 2526 ASSERT(args.length() == 4); |
2527 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); | 2527 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); |
2528 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); | 2528 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); |
2529 // Due to the way the JS calls are constructed this must be less than the | 2529 // Due to the way the JS calls are constructed this must be less than the |
2530 // length of a string, i.e. it is always a Smi. We check anyway for security. | 2530 // length of a string, i.e. it is always a Smi. We check anyway for security. |
2531 CONVERT_SMI_ARG_CHECKED(index, 2); | 2531 CONVERT_SMI_ARG_CHECKED(index, 2); |
2532 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); | 2532 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); |
2533 RUNTIME_ASSERT(index >= 0); | 2533 RUNTIME_ASSERT(index >= 0); |
2534 RUNTIME_ASSERT(index <= subject->length()); | 2534 RUNTIME_ASSERT(index <= subject->length()); |
2535 isolate->counters()->regexp_entry_runtime()->Increment(); | 2535 isolate->counters()->regexp_entry_runtime()->Increment(); |
2536 Handle<Object> result = RegExpImpl::Exec(regexp, | 2536 Handle<Object> result = RegExpImpl::Exec(regexp, |
2537 subject, | 2537 subject, |
2538 index, | 2538 index, |
2539 last_match_info); | 2539 last_match_info); |
2540 RETURN_IF_EMPTY_HANDLE(isolate, result); | 2540 RETURN_IF_EMPTY_HANDLE(isolate, result); |
2541 return *result; | 2541 return *result; |
2542 } | 2542 } |
2543 | 2543 |
2544 | 2544 |
2545 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) { | 2545 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResultInternal) { |
2546 SealHandleScope shs(isolate); | 2546 SealHandleScope shs(isolate); |
2547 ASSERT(args.length() == 3); | 2547 ASSERT(args.length() == 3); |
2548 CONVERT_SMI_ARG_CHECKED(elements_count, 0); | 2548 CONVERT_SMI_ARG_CHECKED(elements_count, 0); |
2549 if (elements_count < 0 || | 2549 if (elements_count < 0 || |
2550 elements_count > FixedArray::kMaxLength || | 2550 elements_count > FixedArray::kMaxLength || |
2551 !Smi::IsValid(elements_count)) { | 2551 !Smi::IsValid(elements_count)) { |
2552 return isolate->ThrowIllegalOperation(); | 2552 return isolate->ThrowIllegalOperation(); |
2553 } | 2553 } |
2554 Object* new_object; | 2554 Object* new_object; |
2555 { MaybeObject* maybe_new_object = | 2555 { MaybeObject* maybe_new_object = |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3197 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, | 3197 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, |
3198 Object* char_code) { | 3198 Object* char_code) { |
3199 if (char_code->IsNumber()) { | 3199 if (char_code->IsNumber()) { |
3200 return isolate->heap()->LookupSingleCharacterStringFromCode( | 3200 return isolate->heap()->LookupSingleCharacterStringFromCode( |
3201 NumberToUint32(char_code) & 0xffff); | 3201 NumberToUint32(char_code) & 0xffff); |
3202 } | 3202 } |
3203 return isolate->heap()->empty_string(); | 3203 return isolate->heap()->empty_string(); |
3204 } | 3204 } |
3205 | 3205 |
3206 | 3206 |
3207 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAt) { | 3207 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCharCodeAtInternal) { |
3208 SealHandleScope shs(isolate); | 3208 SealHandleScope shs(isolate); |
3209 ASSERT(args.length() == 2); | 3209 ASSERT(args.length() == 2); |
3210 | 3210 |
3211 CONVERT_ARG_CHECKED(String, subject, 0); | 3211 CONVERT_ARG_CHECKED(String, subject, 0); |
3212 CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]); | 3212 CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]); |
3213 | 3213 |
3214 // Flatten the string. If someone wants to get a char at an index | 3214 // Flatten the string. If someone wants to get a char at an index |
3215 // in a cons string, it is likely that more indices will be | 3215 // in a cons string, it is likely that more indices will be |
3216 // accessed. | 3216 // accessed. |
3217 Object* flat; | 3217 Object* flat; |
(...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4464 for (int i = 0; i < end; i++) { | 4464 for (int i = 0; i < end; i++) { |
4465 uint16_t char1 = stream1.GetNext(); | 4465 uint16_t char1 = stream1.GetNext(); |
4466 uint16_t char2 = stream2.GetNext(); | 4466 uint16_t char2 = stream2.GetNext(); |
4467 if (char1 != char2) return Smi::FromInt(char1 - char2); | 4467 if (char1 != char2) return Smi::FromInt(char1 - char2); |
4468 } | 4468 } |
4469 | 4469 |
4470 return Smi::FromInt(str1_length - str2_length); | 4470 return Smi::FromInt(str1_length - str2_length); |
4471 } | 4471 } |
4472 | 4472 |
4473 | 4473 |
4474 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) { | 4474 RUNTIME_FUNCTION(MaybeObject*, Runtime_SubStringInternal) { |
4475 HandleScope scope(isolate); | 4475 HandleScope scope(isolate); |
4476 ASSERT(args.length() == 3); | 4476 ASSERT(args.length() == 3); |
4477 | 4477 |
4478 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); | 4478 CONVERT_ARG_HANDLE_CHECKED(String, string, 0); |
4479 int start, end; | 4479 int start, end; |
4480 // We have a fast integer-only case here to avoid a conversion to double in | 4480 // We have a fast integer-only case here to avoid a conversion to double in |
4481 // the common case where from and to are Smis. | 4481 // the common case where from and to are Smis. |
4482 if (args[1]->IsSmi() && args[2]->IsSmi()) { | 4482 if (args[1]->IsSmi() && args[2]->IsSmi()) { |
4483 CONVERT_SMI_ARG_CHECKED(from_number, 1); | 4483 CONVERT_SMI_ARG_CHECKED(from_number, 1); |
4484 CONVERT_SMI_ARG_CHECKED(to_number, 2); | 4484 CONVERT_SMI_ARG_CHECKED(to_number, 2); |
(...skipping 2339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6824 } | 6824 } |
6825 | 6825 |
6826 | 6826 |
6827 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) { | 6827 bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) { |
6828 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; | 6828 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; |
6829 int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars); | 6829 int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars); |
6830 return char_length == 0; | 6830 return char_length == 0; |
6831 } | 6831 } |
6832 | 6832 |
6833 | 6833 |
6834 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToString) { | 6834 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToStringInternal) { |
6835 SealHandleScope shs(isolate); | 6835 SealHandleScope shs(isolate); |
6836 ASSERT(args.length() == 1); | 6836 ASSERT(args.length() == 1); |
6837 | 6837 |
6838 Object* number = args[0]; | 6838 Object* number = args[0]; |
6839 RUNTIME_ASSERT(number->IsNumber()); | 6839 RUNTIME_ASSERT(number->IsNumber()); |
6840 | 6840 |
6841 return isolate->heap()->NumberToString(number); | 6841 return isolate->heap()->NumberToString(number); |
6842 } | 6842 } |
6843 | 6843 |
6844 | 6844 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7028 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberImul) { | 7028 RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberImul) { |
7029 SealHandleScope shs(isolate); | 7029 SealHandleScope shs(isolate); |
7030 ASSERT(args.length() == 2); | 7030 ASSERT(args.length() == 2); |
7031 | 7031 |
7032 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); | 7032 CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]); |
7033 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); | 7033 CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]); |
7034 return isolate->heap()->NumberFromInt32(x * y); | 7034 return isolate->heap()->NumberFromInt32(x * y); |
7035 } | 7035 } |
7036 | 7036 |
7037 | 7037 |
7038 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAdd) { | 7038 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringAddInternal) { |
7039 HandleScope scope(isolate); | 7039 HandleScope scope(isolate); |
7040 ASSERT(args.length() == 2); | 7040 ASSERT(args.length() == 2); |
7041 CONVERT_ARG_HANDLE_CHECKED(String, str1, 0); | 7041 CONVERT_ARG_HANDLE_CHECKED(String, str1, 0); |
7042 CONVERT_ARG_HANDLE_CHECKED(String, str2, 1); | 7042 CONVERT_ARG_HANDLE_CHECKED(String, str2, 1); |
7043 isolate->counters()->string_add_runtime()->Increment(); | 7043 isolate->counters()->string_add_runtime()->Increment(); |
7044 Handle<String> result = isolate->factory()->NewConsString(str1, str2); | 7044 Handle<String> result = isolate->factory()->NewConsString(str1, str2); |
7045 RETURN_IF_EMPTY_HANDLE(isolate, result); | 7045 RETURN_IF_EMPTY_HANDLE(isolate, result); |
7046 return *result; | 7046 return *result; |
7047 } | 7047 } |
7048 | 7048 |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7648 result = equal_prefix_result; | 7648 result = equal_prefix_result; |
7649 } else { | 7649 } else { |
7650 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); | 7650 result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER); |
7651 } | 7651 } |
7652 ASSERT(result == | 7652 ASSERT(result == |
7653 StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y)); | 7653 StringCharacterStreamCompare(x->GetIsolate()->runtime_state(), x, y)); |
7654 return result; | 7654 return result; |
7655 } | 7655 } |
7656 | 7656 |
7657 | 7657 |
7658 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompare) { | 7658 RUNTIME_FUNCTION(MaybeObject*, Runtime_StringCompareInternal) { |
7659 SealHandleScope shs(isolate); | 7659 SealHandleScope shs(isolate); |
7660 ASSERT(args.length() == 2); | 7660 ASSERT(args.length() == 2); |
7661 | 7661 |
7662 CONVERT_ARG_CHECKED(String, x, 0); | 7662 CONVERT_ARG_CHECKED(String, x, 0); |
7663 CONVERT_ARG_CHECKED(String, y, 1); | 7663 CONVERT_ARG_CHECKED(String, y, 1); |
7664 | 7664 |
7665 isolate->counters()->string_compare_runtime()->Increment(); | 7665 isolate->counters()->string_compare_runtime()->Increment(); |
7666 | 7666 |
7667 // A few fast case tests before we flatten. | 7667 // A few fast case tests before we flatten. |
7668 if (x == y) return Smi::FromInt(EQUAL); | 7668 if (x == y) return Smi::FromInt(EQUAL); |
(...skipping 6810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14479 // This call must not cause lazy deopts, because it's called from deferred | 14479 // This call must not cause lazy deopts, because it's called from deferred |
14480 // code where we can't handle lazy deopts for lack of a suitable bailout | 14480 // code where we can't handle lazy deopts for lack of a suitable bailout |
14481 // ID. So we just try migration and signal failure if necessary, | 14481 // ID. So we just try migration and signal failure if necessary, |
14482 // which will also trigger a deopt. | 14482 // which will also trigger a deopt. |
14483 Handle<Object> result = JSObject::TryMigrateInstance(js_object); | 14483 Handle<Object> result = JSObject::TryMigrateInstance(js_object); |
14484 if (result.is_null()) return Smi::FromInt(0); | 14484 if (result.is_null()) return Smi::FromInt(0); |
14485 return *object; | 14485 return *object; |
14486 } | 14486 } |
14487 | 14487 |
14488 | 14488 |
14489 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCache) { | 14489 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetFromCacheInternal) { |
14490 SealHandleScope shs(isolate); | 14490 SealHandleScope shs(isolate); |
14491 // This is only called from codegen, so checks might be more lax. | 14491 // This is only called from codegen, so checks might be more lax. |
14492 CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0); | 14492 CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0); |
14493 Object* key = args[1]; | 14493 Object* key = args[1]; |
14494 | 14494 |
14495 int finger_index = cache->finger_index(); | 14495 int finger_index = cache->finger_index(); |
14496 Object* o = cache->get(finger_index); | 14496 Object* o = cache->get(finger_index); |
14497 if (o == key) { | 14497 if (o == key) { |
14498 // The fastest case: hit the same place again. | 14498 // The fastest case: hit the same place again. |
14499 return cache->get(finger_index + 1); | 14499 return cache->get(finger_index + 1); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14637 inline_runtime_functions = true; | 14637 inline_runtime_functions = true; |
14638 INLINE_FUNCTION_LIST(ADD_ENTRY) | 14638 INLINE_FUNCTION_LIST(ADD_ENTRY) |
14639 #undef ADD_ENTRY | 14639 #undef ADD_ENTRY |
14640 ASSERT_EQ(index, entry_count); | 14640 ASSERT_EQ(index, entry_count); |
14641 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); | 14641 Handle<JSArray> result = factory->NewJSArrayWithElements(elements); |
14642 return *result; | 14642 return *result; |
14643 } | 14643 } |
14644 #endif | 14644 #endif |
14645 | 14645 |
14646 | 14646 |
14647 RUNTIME_FUNCTION(MaybeObject*, Runtime_Log) { | 14647 RUNTIME_FUNCTION(MaybeObject*, Runtime_LogInternal) { |
14648 HandleScope handle_scope(isolate); | 14648 HandleScope handle_scope(isolate); |
14649 ASSERT(args.length() == 2); | 14649 ASSERT(args.length() == 2); |
14650 CONVERT_ARG_HANDLE_CHECKED(String, format, 0); | 14650 CONVERT_ARG_HANDLE_CHECKED(String, format, 0); |
14651 CONVERT_ARG_HANDLE_CHECKED(JSArray, elms, 1); | 14651 CONVERT_ARG_HANDLE_CHECKED(JSArray, elms, 1); |
14652 | 14652 |
14653 SmartArrayPointer<char> format_chars = format->ToCString(); | 14653 SmartArrayPointer<char> format_chars = format->ToCString(); |
14654 isolate->logger()->LogRuntime( | 14654 isolate->logger()->LogRuntime( |
14655 Vector<const char>(format_chars.get(), format->length()), elms); | 14655 Vector<const char>(format_chars.get(), format->length()), elms); |
14656 return isolate->heap()->undefined_value(); | 14656 return isolate->heap()->undefined_value(); |
14657 } | 14657 } |
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14986 | 14986 |
14987 #define F(name, number_of_args, result_size) \ | 14987 #define F(name, number_of_args, result_size) \ |
14988 { Runtime::k##name, Runtime::RUNTIME, #name, \ | 14988 { Runtime::k##name, Runtime::RUNTIME, #name, \ |
14989 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, | 14989 FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
14990 | 14990 |
14991 | 14991 |
14992 #define I(name, number_of_args, result_size) \ | 14992 #define I(name, number_of_args, result_size) \ |
14993 { Runtime::kInline##name, Runtime::INLINE, \ | 14993 { Runtime::kInline##name, Runtime::INLINE, \ |
14994 "_" #name, NULL, number_of_args, result_size }, | 14994 "_" #name, NULL, number_of_args, result_size }, |
14995 | 14995 |
| 14996 |
| 14997 #define IO(name, number_of_args, result_size) \ |
| 14998 { Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, \ |
| 14999 "_" #name, FUNCTION_ADDR(Runtime_##name), number_of_args, result_size }, |
| 15000 |
| 15001 |
14996 static const Runtime::Function kIntrinsicFunctions[] = { | 15002 static const Runtime::Function kIntrinsicFunctions[] = { |
14997 RUNTIME_FUNCTION_LIST(F) | 15003 RUNTIME_FUNCTION_LIST(F) |
14998 INLINE_FUNCTION_LIST(I) | 15004 INLINE_FUNCTION_LIST(I) |
| 15005 INLINE_OPTIMIZED_FUNCTION_LIST(IO) |
14999 }; | 15006 }; |
15000 | 15007 |
| 15008 #undef IO |
15001 #undef I | 15009 #undef I |
15002 #undef F | 15010 #undef F |
15003 | 15011 |
15004 | 15012 |
15005 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap, | 15013 MaybeObject* Runtime::InitializeIntrinsicFunctionNames(Heap* heap, |
15006 Object* dictionary) { | 15014 Object* dictionary) { |
15007 ASSERT(dictionary != NULL); | 15015 ASSERT(dictionary != NULL); |
15008 ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0); | 15016 ASSERT(NameDictionary::cast(dictionary)->NumberOfElements() == 0); |
15009 for (int i = 0; i < kNumFunctions; ++i) { | 15017 for (int i = 0; i < kNumFunctions; ++i) { |
15010 Object* name_string; | 15018 Object* name_string; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15060 // Handle last resort GC and make sure to allow future allocations | 15068 // Handle last resort GC and make sure to allow future allocations |
15061 // to grow the heap without causing GCs (if possible). | 15069 // to grow the heap without causing GCs (if possible). |
15062 isolate->counters()->gc_last_resort_from_js()->Increment(); | 15070 isolate->counters()->gc_last_resort_from_js()->Increment(); |
15063 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 15071 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
15064 "Runtime::PerformGC"); | 15072 "Runtime::PerformGC"); |
15065 } | 15073 } |
15066 } | 15074 } |
15067 | 15075 |
15068 | 15076 |
15069 } } // namespace v8::internal | 15077 } } // namespace v8::internal |
OLD | NEW |