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 5908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5919 int length, | 5919 int length, |
5920 int input_string_length, | 5920 int input_string_length, |
5921 unibrow::Mapping<Converter, 128>* mapping) { | 5921 unibrow::Mapping<Converter, 128>* mapping) { |
5922 // We try this twice, once with the assumption that the result is no longer | 5922 // We try this twice, once with the assumption that the result is no longer |
5923 // than the input and, if that assumption breaks, again with the exact | 5923 // than the input and, if that assumption breaks, again with the exact |
5924 // length. This may not be pretty, but it is nicer than what was here before | 5924 // length. This may not be pretty, but it is nicer than what was here before |
5925 // and I hereby claim my vaffel-is. | 5925 // and I hereby claim my vaffel-is. |
5926 // | 5926 // |
5927 // Allocate the resulting string. | 5927 // Allocate the resulting string. |
5928 // | 5928 // |
5929 // NOTE: This assumes that the upper/lower case of an ascii | 5929 // NOTE: This assumes that the upper/lower case of an ASCII |
5930 // character is also ascii. This is currently the case, but it | 5930 // character is also ASCII. This is currently the case, but it |
5931 // might break in the future if we implement more context and locale | 5931 // might break in the future if we implement more context and locale |
5932 // dependent upper/lower conversions. | 5932 // dependent upper/lower conversions. |
5933 Object* o; | 5933 Object* o; |
5934 { MaybeObject* maybe_o = s->IsAsciiRepresentation() | 5934 { MaybeObject* maybe_o = s->IsAsciiRepresentation() |
5935 ? isolate->heap()->AllocateRawAsciiString(length) | 5935 ? isolate->heap()->AllocateRawAsciiString(length) |
5936 : isolate->heap()->AllocateRawTwoByteString(length); | 5936 : isolate->heap()->AllocateRawTwoByteString(length); |
5937 if (!maybe_o->ToObject(&o)) return maybe_o; | 5937 if (!maybe_o->ToObject(&o)) return maybe_o; |
5938 } | 5938 } |
5939 String* result = String::cast(o); | 5939 String* result = String::cast(o); |
5940 bool has_changed_character = false; | 5940 bool has_changed_character = false; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6020 | 6020 |
6021 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; | 6021 static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF; |
6022 | 6022 |
6023 | 6023 |
6024 // Given a word and two range boundaries returns a word with high bit | 6024 // Given a word and two range boundaries returns a word with high bit |
6025 // set in every byte iff the corresponding input byte was strictly in | 6025 // set in every byte iff the corresponding input byte was strictly in |
6026 // the range (m, n). All the other bits in the result are cleared. | 6026 // the range (m, n). All the other bits in the result are cleared. |
6027 // This function is only useful when it can be inlined and the | 6027 // This function is only useful when it can be inlined and the |
6028 // boundaries are statically known. | 6028 // boundaries are statically known. |
6029 // Requires: all bytes in the input word and the boundaries must be | 6029 // Requires: all bytes in the input word and the boundaries must be |
6030 // ascii (less than 0x7F). | 6030 // ASCII (less than 0x7F). |
6031 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { | 6031 static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) { |
6032 // Every byte in an ascii string is less than or equal to 0x7F. | 6032 // Every byte in an ASCII string is less than or equal to 0x7F. |
6033 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); | 6033 ASSERT((w & (kOneInEveryByte * 0x7F)) == w); |
6034 // Use strict inequalities since in edge cases the function could be | 6034 // Use strict inequalities since in edge cases the function could be |
6035 // further simplified. | 6035 // further simplified. |
6036 ASSERT(0 < m && m < n && n < 0x7F); | 6036 ASSERT(0 < m && m < n && n < 0x7F); |
6037 // Has high bit set in every w byte less than n. | 6037 // Has high bit set in every w byte less than n. |
6038 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; | 6038 uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w; |
6039 // Has high bit set in every w byte greater than m. | 6039 // Has high bit set in every w byte greater than m. |
6040 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); | 6040 uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m); |
6041 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); | 6041 return (tmp1 & tmp2 & (kOneInEveryByte * 0x80)); |
6042 } | 6042 } |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6150 Isolate* isolate, | 6150 Isolate* isolate, |
6151 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { | 6151 unibrow::Mapping<typename ConvertTraits::UnibrowConverter, 128>* mapping) { |
6152 NoHandleAllocation ha; | 6152 NoHandleAllocation ha; |
6153 CONVERT_CHECKED(String, s, args[0]); | 6153 CONVERT_CHECKED(String, s, args[0]); |
6154 s = s->TryFlattenGetString(); | 6154 s = s->TryFlattenGetString(); |
6155 | 6155 |
6156 const int length = s->length(); | 6156 const int length = s->length(); |
6157 // Assume that the string is not empty; we need this assumption later | 6157 // Assume that the string is not empty; we need this assumption later |
6158 if (length == 0) return s; | 6158 if (length == 0) return s; |
6159 | 6159 |
6160 // Simpler handling of ascii strings. | 6160 // Simpler handling of ASCII strings. |
6161 // | 6161 // |
6162 // NOTE: This assumes that the upper/lower case of an ascii | 6162 // NOTE: This assumes that the upper/lower case of an ASCII |
6163 // character is also ascii. This is currently the case, but it | 6163 // character is also ASCII. This is currently the case, but it |
6164 // might break in the future if we implement more context and locale | 6164 // might break in the future if we implement more context and locale |
6165 // dependent upper/lower conversions. | 6165 // dependent upper/lower conversions. |
6166 if (s->IsSeqAsciiString()) { | 6166 if (s->IsSeqAsciiString()) { |
6167 Object* o; | 6167 Object* o; |
6168 { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length); | 6168 { MaybeObject* maybe_o = isolate->heap()->AllocateRawAsciiString(length); |
6169 if (!maybe_o->ToObject(&o)) return maybe_o; | 6169 if (!maybe_o->ToObject(&o)) return maybe_o; |
6170 } | 6170 } |
6171 SeqAsciiString* result = SeqAsciiString::cast(o); | 6171 SeqAsciiString* result = SeqAsciiString::cast(o); |
6172 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( | 6172 bool has_changed_character = ConvertTraits::AsciiConverter::Convert( |
6173 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); | 6173 result->GetChars(), SeqAsciiString::cast(s)->GetChars(), length); |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6316 *subject, | 6316 *subject, |
6317 *pattern, | 6317 *pattern, |
6318 *elements); | 6318 *elements); |
6319 } | 6319 } |
6320 } | 6320 } |
6321 | 6321 |
6322 return *result; | 6322 return *result; |
6323 } | 6323 } |
6324 | 6324 |
6325 | 6325 |
6326 // Copies ascii characters to the given fixed array looking up | 6326 // Copies ASCII characters to the given fixed array looking up |
6327 // one-char strings in the cache. Gives up on the first char that is | 6327 // one-char strings in the cache. Gives up on the first char that is |
6328 // not in the cache and fills the remainder with smi zeros. Returns | 6328 // not in the cache and fills the remainder with smi zeros. Returns |
6329 // the length of the successfully copied prefix. | 6329 // the length of the successfully copied prefix. |
6330 static int CopyCachedAsciiCharsToArray(Heap* heap, | 6330 static int CopyCachedAsciiCharsToArray(Heap* heap, |
6331 const char* chars, | 6331 const char* chars, |
6332 FixedArray* elements, | 6332 FixedArray* elements, |
6333 int length) { | 6333 int length) { |
6334 AssertNoAllocation no_gc; | 6334 AssertNoAllocation no_gc; |
6335 FixedArray* ascii_cache = heap->single_character_string_cache(); | 6335 FixedArray* ascii_cache = heap->single_character_string_cache(); |
6336 Object* undefined = heap->undefined_value(); | 6336 Object* undefined = heap->undefined_value(); |
(...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7415 } else if (y == -0.5) { | 7415 } else if (y == -0.5) { |
7416 result = (isinf(x)) ? 0 : 1.0 / sqrt(x + 0.0); // Convert -0 to +0. | 7416 result = (isinf(x)) ? 0 : 1.0 / sqrt(x + 0.0); // Convert -0 to +0. |
7417 } else { | 7417 } else { |
7418 result = power_double_double(x, y); | 7418 result = power_double_double(x, y); |
7419 } | 7419 } |
7420 if (isnan(result)) return isolate->heap()->nan_value(); | 7420 if (isnan(result)) return isolate->heap()->nan_value(); |
7421 return isolate->heap()->AllocateHeapNumber(result); | 7421 return isolate->heap()->AllocateHeapNumber(result); |
7422 } | 7422 } |
7423 | 7423 |
7424 // Fast version of Math.pow if we know that y is not an integer and y is not | 7424 // Fast version of Math.pow if we know that y is not an integer and y is not |
7425 // -0.5 or 0.5. Used as slow case from fullcodegen. | 7425 // -0.5 or 0.5. Used as slow case from full codegen. |
7426 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) { | 7426 RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) { |
7427 NoHandleAllocation ha; | 7427 NoHandleAllocation ha; |
7428 ASSERT(args.length() == 2); | 7428 ASSERT(args.length() == 2); |
7429 isolate->counters()->math_pow()->Increment(); | 7429 isolate->counters()->math_pow()->Increment(); |
7430 | 7430 |
7431 CONVERT_DOUBLE_ARG_CHECKED(x, 0); | 7431 CONVERT_DOUBLE_ARG_CHECKED(x, 0); |
7432 CONVERT_DOUBLE_ARG_CHECKED(y, 1); | 7432 CONVERT_DOUBLE_ARG_CHECKED(y, 1); |
7433 if (y == 0) { | 7433 if (y == 0) { |
7434 return Smi::FromInt(1); | 7434 return Smi::FromInt(1); |
7435 } else { | 7435 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
7458 int sign = number->get_sign(); | 7458 int sign = number->get_sign(); |
7459 | 7459 |
7460 if (exponent < -1) { | 7460 if (exponent < -1) { |
7461 // Number in range ]-0.5..0.5[. These always round to +/-zero. | 7461 // Number in range ]-0.5..0.5[. These always round to +/-zero. |
7462 if (sign) return isolate->heap()->minus_zero_value(); | 7462 if (sign) return isolate->heap()->minus_zero_value(); |
7463 return Smi::FromInt(0); | 7463 return Smi::FromInt(0); |
7464 } | 7464 } |
7465 | 7465 |
7466 // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and | 7466 // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and |
7467 // should be rounded to 2^30, which is not smi (for 31-bit smis, similar | 7467 // should be rounded to 2^30, which is not smi (for 31-bit smis, similar |
7468 // agument holds for 32-bit smis). | 7468 // argument holds for 32-bit smis). |
7469 if (!sign && exponent < kSmiValueSize - 2) { | 7469 if (!sign && exponent < kSmiValueSize - 2) { |
7470 return Smi::FromInt(static_cast<int>(value + 0.5)); | 7470 return Smi::FromInt(static_cast<int>(value + 0.5)); |
7471 } | 7471 } |
7472 | 7472 |
7473 // If the magnitude is big enough, there's no place for fraction part. If we | 7473 // If the magnitude is big enough, there's no place for fraction part. If we |
7474 // try to add 0.5 to this number, 1.0 will be added instead. | 7474 // try to add 0.5 to this number, 1.0 will be added instead. |
7475 if (exponent >= 52) { | 7475 if (exponent >= 52) { |
7476 return number; | 7476 return number; |
7477 } | 7477 } |
7478 | 7478 |
(...skipping 1869 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9348 return JSGlobalObject::cast(global)->global_receiver(); | 9348 return JSGlobalObject::cast(global)->global_receiver(); |
9349 } | 9349 } |
9350 | 9350 |
9351 | 9351 |
9352 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { | 9352 RUNTIME_FUNCTION(MaybeObject*, Runtime_ParseJson) { |
9353 HandleScope scope(isolate); | 9353 HandleScope scope(isolate); |
9354 ASSERT_EQ(1, args.length()); | 9354 ASSERT_EQ(1, args.length()); |
9355 CONVERT_ARG_CHECKED(String, source, 0); | 9355 CONVERT_ARG_CHECKED(String, source, 0); |
9356 | 9356 |
9357 source = Handle<String>(source->TryFlattenGetString()); | 9357 source = Handle<String>(source->TryFlattenGetString()); |
9358 // Optimized fast case where we only have ascii characters. | 9358 // Optimized fast case where we only have ASCII characters. |
9359 Handle<Object> result; | 9359 Handle<Object> result; |
9360 if (source->IsSeqAsciiString()) { | 9360 if (source->IsSeqAsciiString()) { |
9361 result = JsonParser<true>::Parse(source); | 9361 result = JsonParser<true>::Parse(source); |
9362 } else { | 9362 } else { |
9363 result = JsonParser<false>::Parse(source); | 9363 result = JsonParser<false>::Parse(source); |
9364 } | 9364 } |
9365 if (result.is_null()) { | 9365 if (result.is_null()) { |
9366 // Syntax error or stack overflow in scanner. | 9366 // Syntax error or stack overflow in scanner. |
9367 ASSERT(isolate->has_pending_exception()); | 9367 ASSERT(isolate->has_pending_exception()); |
9368 return Failure::Exception(); | 9368 return Failure::Exception(); |
(...skipping 881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10250 uint32_t min_length = actual_length < length ? actual_length : length; | 10250 uint32_t min_length = actual_length < length ? actual_length : length; |
10251 Handle<Object> length_object = | 10251 Handle<Object> length_object = |
10252 isolate->factory()->NewNumber(static_cast<double>(min_length)); | 10252 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
10253 single_interval->set(1, *length_object); | 10253 single_interval->set(1, *length_object); |
10254 return *isolate->factory()->NewJSArrayWithElements(single_interval); | 10254 return *isolate->factory()->NewJSArrayWithElements(single_interval); |
10255 } | 10255 } |
10256 } | 10256 } |
10257 | 10257 |
10258 | 10258 |
10259 // DefineAccessor takes an optional final argument which is the | 10259 // DefineAccessor takes an optional final argument which is the |
10260 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due | 10260 // property attributes (e.g. DONT_ENUM, DONT_DELETE). IMPORTANT: due |
10261 // to the way accessors are implemented, it is set for both the getter | 10261 // to the way accessors are implemented, it is set for both the getter |
10262 // and setter on the first call to DefineAccessor and ignored on | 10262 // and setter on the first call to DefineAccessor and ignored on |
10263 // subsequent calls. | 10263 // subsequent calls. |
10264 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineAccessor) { | 10264 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineAccessor) { |
10265 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); | 10265 RUNTIME_ASSERT(args.length() == 4 || args.length() == 5); |
10266 // Compute attributes. | 10266 // Compute attributes. |
10267 PropertyAttributes attributes = NONE; | 10267 PropertyAttributes attributes = NONE; |
10268 if (args.length() == 5) { | 10268 if (args.length() == 5) { |
10269 CONVERT_CHECKED(Smi, attrs, args[4]); | 10269 CONVERT_CHECKED(Smi, attrs, args[4]); |
10270 int value = attrs->value(); | 10270 int value = attrs->value(); |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11082 | 11082 |
11083 // Create a plain JSObject which materializes the closure content for the | 11083 // Create a plain JSObject which materializes the closure content for the |
11084 // context. | 11084 // context. |
11085 static Handle<JSObject> MaterializeClosure(Isolate* isolate, | 11085 static Handle<JSObject> MaterializeClosure(Isolate* isolate, |
11086 Handle<Context> context) { | 11086 Handle<Context> context) { |
11087 ASSERT(context->IsFunctionContext()); | 11087 ASSERT(context->IsFunctionContext()); |
11088 | 11088 |
11089 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 11089 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
11090 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11090 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11091 | 11091 |
11092 // Allocate and initialize a JSObject with all the content of theis function | 11092 // Allocate and initialize a JSObject with all the content of this function |
11093 // closure. | 11093 // closure. |
11094 Handle<JSObject> closure_scope = | 11094 Handle<JSObject> closure_scope = |
11095 isolate->factory()->NewJSObject(isolate->object_function()); | 11095 isolate->factory()->NewJSObject(isolate->object_function()); |
11096 | 11096 |
11097 // Fill all context locals to the context extension. | 11097 // Fill all context locals to the context extension. |
11098 if (!CopyContextLocalsToScopeObject( | 11098 if (!CopyContextLocalsToScopeObject( |
11099 isolate, scope_info, context, closure_scope)) { | 11099 isolate, scope_info, context, closure_scope)) { |
11100 return Handle<JSObject>(); | 11100 return Handle<JSObject>(); |
11101 } | 11101 } |
11102 | 11102 |
(...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12250 // Fill the script objects. | 12250 // Fill the script objects. |
12251 Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts(); | 12251 Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts(); |
12252 | 12252 |
12253 // Convert the script objects to proper JS objects. | 12253 // Convert the script objects to proper JS objects. |
12254 for (int i = 0; i < instances->length(); i++) { | 12254 for (int i = 0; i < instances->length(); i++) { |
12255 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); | 12255 Handle<Script> script = Handle<Script>(Script::cast(instances->get(i))); |
12256 // Get the script wrapper in a local handle before calling GetScriptWrapper, | 12256 // Get the script wrapper in a local handle before calling GetScriptWrapper, |
12257 // because using | 12257 // because using |
12258 // instances->set(i, *GetScriptWrapper(script)) | 12258 // instances->set(i, *GetScriptWrapper(script)) |
12259 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might | 12259 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might |
12260 // already have deferenced the instances handle. | 12260 // already have dereferenced the instances handle. |
12261 Handle<JSValue> wrapper = GetScriptWrapper(script); | 12261 Handle<JSValue> wrapper = GetScriptWrapper(script); |
12262 instances->set(i, *wrapper); | 12262 instances->set(i, *wrapper); |
12263 } | 12263 } |
12264 | 12264 |
12265 // Return result as a JS array. | 12265 // Return result as a JS array. |
12266 Handle<JSObject> result = | 12266 Handle<JSObject> result = |
12267 isolate->factory()->NewJSObject(isolate->array_function()); | 12267 isolate->factory()->NewJSObject(isolate->array_function()); |
12268 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); | 12268 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); |
12269 return *result; | 12269 return *result; |
12270 } | 12270 } |
(...skipping 1281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13552 } else { | 13552 } else { |
13553 // Handle last resort GC and make sure to allow future allocations | 13553 // Handle last resort GC and make sure to allow future allocations |
13554 // to grow the heap without causing GCs (if possible). | 13554 // to grow the heap without causing GCs (if possible). |
13555 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13555 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13556 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); | 13556 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); |
13557 } | 13557 } |
13558 } | 13558 } |
13559 | 13559 |
13560 | 13560 |
13561 } } // namespace v8::internal | 13561 } } // namespace v8::internal |
OLD | NEW |