| 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 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 proxy->Fix(); | 648 proxy->Fix(); |
| 649 return isolate->heap()->undefined_value(); | 649 return isolate->heap()->undefined_value(); |
| 650 } | 650 } |
| 651 | 651 |
| 652 | 652 |
| 653 static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, | 653 static void ArrayBufferWeakCallback(v8::Isolate* external_isolate, |
| 654 Persistent<Value>* object, | 654 Persistent<Value>* object, |
| 655 void* data) { | 655 void* data) { |
| 656 Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate); | 656 Isolate* isolate = reinterpret_cast<Isolate*>(external_isolate); |
| 657 HandleScope scope(isolate); | 657 HandleScope scope(isolate); |
| 658 Handle<Object> internal_object = Utils::OpenHandle(**object); | 658 Handle<Object> internal_object = Utils::OpenPersistent(object); |
| 659 Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(*internal_object)); | 659 Handle<JSArrayBuffer> array_buffer(JSArrayBuffer::cast(*internal_object)); |
| 660 | 660 |
| 661 if (!array_buffer->is_external()) { | 661 if (!array_buffer->is_external()) { |
| 662 size_t allocated_length = NumberToSize( | 662 size_t allocated_length = NumberToSize( |
| 663 isolate, array_buffer->byte_length()); | 663 isolate, array_buffer->byte_length()); |
| 664 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( | 664 isolate->heap()->AdjustAmountOfExternalAllocatedMemory( |
| 665 -static_cast<intptr_t>(allocated_length)); | 665 -static_cast<intptr_t>(allocated_length)); |
| 666 CHECK(V8::ArrayBufferAllocator() != NULL); | 666 CHECK(V8::ArrayBufferAllocator() != NULL); |
| 667 V8::ArrayBufferAllocator()->Free(data); | 667 V8::ArrayBufferAllocator()->Free(data); |
| 668 } | 668 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 if (allocated_length != 0) { | 704 if (allocated_length != 0) { |
| 705 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); | 705 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); |
| 706 if (data == NULL) return false; | 706 if (data == NULL) return false; |
| 707 memset(data, 0, allocated_length); | 707 memset(data, 0, allocated_length); |
| 708 } else { | 708 } else { |
| 709 data = NULL; | 709 data = NULL; |
| 710 } | 710 } |
| 711 | 711 |
| 712 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); | 712 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); |
| 713 | 713 |
| 714 v8::Isolate* external_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 714 Handle<Object> persistent = isolate->global_handles()->Create(*array_buffer); |
| 715 v8::Persistent<v8::Value> weak_handle( | 715 GlobalHandles::MakeWeak(persistent.location(), data, ArrayBufferWeakCallback); |
| 716 external_isolate, v8::Utils::ToLocal(Handle<Object>::cast(array_buffer))); | 716 GlobalHandles::MarkIndependent(persistent.location()); |
| 717 weak_handle.MakeWeak(external_isolate, data, ArrayBufferWeakCallback); | 717 |
| 718 weak_handle.MarkIndependent(external_isolate); | |
| 719 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); | 718 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); |
| 720 | 719 |
| 721 return true; | 720 return true; |
| 722 } | 721 } |
| 723 | 722 |
| 724 | 723 |
| 725 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { | 724 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { |
| 726 HandleScope scope(isolate); | 725 HandleScope scope(isolate); |
| 727 ASSERT(args.length() == 2); | 726 ASSERT(args.length() == 2); |
| 728 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); | 727 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| (...skipping 3778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4507 return receiver->FastPropertyAt(result.representation(), offset); | 4506 return receiver->FastPropertyAt(result.representation(), offset); |
| 4508 } | 4507 } |
| 4509 } else { | 4508 } else { |
| 4510 // Attempt dictionary lookup. | 4509 // Attempt dictionary lookup. |
| 4511 NameDictionary* dictionary = receiver->property_dictionary(); | 4510 NameDictionary* dictionary = receiver->property_dictionary(); |
| 4512 int entry = dictionary->FindEntry(key); | 4511 int entry = dictionary->FindEntry(key); |
| 4513 if ((entry != NameDictionary::kNotFound) && | 4512 if ((entry != NameDictionary::kNotFound) && |
| 4514 (dictionary->DetailsAt(entry).type() == NORMAL)) { | 4513 (dictionary->DetailsAt(entry).type() == NORMAL)) { |
| 4515 Object* value = dictionary->ValueAt(entry); | 4514 Object* value = dictionary->ValueAt(entry); |
| 4516 if (!receiver->IsGlobalObject()) return value; | 4515 if (!receiver->IsGlobalObject()) return value; |
| 4517 value = JSGlobalPropertyCell::cast(value)->value(); | 4516 value = PropertyCell::cast(value)->value(); |
| 4518 if (!value->IsTheHole()) return value; | 4517 if (!value->IsTheHole()) return value; |
| 4519 // If value is the hole do the general lookup. | 4518 // If value is the hole do the general lookup. |
| 4520 } | 4519 } |
| 4521 } | 4520 } |
| 4522 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { | 4521 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { |
| 4523 // JSObject without a name key. If the key is a Smi, check for a | 4522 // JSObject without a name key. If the key is a Smi, check for a |
| 4524 // definite out-of-bounds access to elements, which is a strong indicator | 4523 // definite out-of-bounds access to elements, which is a strong indicator |
| 4525 // that subsequent accesses will also call the runtime. Proactively | 4524 // that subsequent accesses will also call the runtime. Proactively |
| 4526 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of | 4525 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of |
| 4527 // doubles for those future calls in the case that the elements would | 4526 // doubles for those future calls in the case that the elements would |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4747 // JavaScript. | 4746 // JavaScript. |
| 4748 // In the case of a String object we just need to redirect the assignment to | 4747 // In the case of a String object we just need to redirect the assignment to |
| 4749 // the underlying string if the index is in range. Since the underlying | 4748 // the underlying string if the index is in range. Since the underlying |
| 4750 // string does nothing with the assignment then we can ignore such | 4749 // string does nothing with the assignment then we can ignore such |
| 4751 // assignments. | 4750 // assignments. |
| 4752 if (js_object->IsStringObjectWithCharacterAt(index)) { | 4751 if (js_object->IsStringObjectWithCharacterAt(index)) { |
| 4753 return *value; | 4752 return *value; |
| 4754 } | 4753 } |
| 4755 | 4754 |
| 4756 js_object->ValidateElements(); | 4755 js_object->ValidateElements(); |
| 4757 Handle<Object> result = JSObject::SetElement( | 4756 if (js_object->HasExternalArrayElements()) { |
| 4758 js_object, index, value, attr, strict_mode, set_mode); | 4757 if (!value->IsNumber() && !value->IsUndefined()) { |
| 4758 bool has_exception; |
| 4759 Handle<Object> number = Execution::ToNumber(value, &has_exception); |
| 4760 if (has_exception) return Failure::Exception(); |
| 4761 value = number; |
| 4762 } |
| 4763 } |
| 4764 MaybeObject* result = js_object->SetElement( |
| 4765 index, *value, attr, strict_mode, true, set_mode); |
| 4759 js_object->ValidateElements(); | 4766 js_object->ValidateElements(); |
| 4760 if (result.is_null()) return Failure::Exception(); | 4767 if (result->IsFailure()) return result; |
| 4761 return *value; | 4768 return *value; |
| 4762 } | 4769 } |
| 4763 | 4770 |
| 4764 if (key->IsName()) { | 4771 if (key->IsName()) { |
| 4765 Handle<Object> result; | 4772 MaybeObject* result; |
| 4766 Handle<Name> name = Handle<Name>::cast(key); | 4773 Handle<Name> name = Handle<Name>::cast(key); |
| 4767 if (name->AsArrayIndex(&index)) { | 4774 if (name->AsArrayIndex(&index)) { |
| 4768 result = JSObject::SetElement( | 4775 if (js_object->HasExternalArrayElements()) { |
| 4769 js_object, index, value, attr, strict_mode, set_mode); | 4776 if (!value->IsNumber() && !value->IsUndefined()) { |
| 4777 bool has_exception; |
| 4778 Handle<Object> number = Execution::ToNumber(value, &has_exception); |
| 4779 if (has_exception) return Failure::Exception(); |
| 4780 value = number; |
| 4781 } |
| 4782 } |
| 4783 result = js_object->SetElement( |
| 4784 index, *value, attr, strict_mode, true, set_mode); |
| 4770 } else { | 4785 } else { |
| 4771 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); | 4786 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); |
| 4772 result = JSReceiver::SetProperty( | 4787 result = js_object->SetProperty(*name, *value, attr, strict_mode); |
| 4773 js_object, name, value, attr, strict_mode); | |
| 4774 } | 4788 } |
| 4775 if (result.is_null()) return Failure::Exception(); | 4789 if (result->IsFailure()) return result; |
| 4776 return *value; | 4790 return *value; |
| 4777 } | 4791 } |
| 4778 | 4792 |
| 4779 // Call-back into JavaScript to convert the key to a string. | 4793 // Call-back into JavaScript to convert the key to a string. |
| 4780 bool has_pending_exception = false; | 4794 bool has_pending_exception = false; |
| 4781 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); | 4795 Handle<Object> converted = Execution::ToString(key, &has_pending_exception); |
| 4782 if (has_pending_exception) return Failure::Exception(); | 4796 if (has_pending_exception) return Failure::Exception(); |
| 4783 Handle<String> name = Handle<String>::cast(converted); | 4797 Handle<String> name = Handle<String>::cast(converted); |
| 4784 | 4798 |
| 4785 if (name->AsArrayIndex(&index)) { | 4799 if (name->AsArrayIndex(&index)) { |
| (...skipping 3278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8064 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) { | 8078 RUNTIME_FUNCTION(MaybeObject*, Runtime_RunningInSimulator) { |
| 8065 SealHandleScope shs(isolate); | 8079 SealHandleScope shs(isolate); |
| 8066 #if defined(USE_SIMULATOR) | 8080 #if defined(USE_SIMULATOR) |
| 8067 return isolate->heap()->true_value(); | 8081 return isolate->heap()->true_value(); |
| 8068 #else | 8082 #else |
| 8069 return isolate->heap()->false_value(); | 8083 return isolate->heap()->false_value(); |
| 8070 #endif | 8084 #endif |
| 8071 } | 8085 } |
| 8072 | 8086 |
| 8073 | 8087 |
| 8088 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsParallelRecompilationSupported) { |
| 8089 HandleScope scope(isolate); |
| 8090 return FLAG_parallel_recompilation |
| 8091 ? isolate->heap()->true_value() : isolate->heap()->false_value(); |
| 8092 } |
| 8093 |
| 8094 |
| 8074 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) { | 8095 RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) { |
| 8075 HandleScope scope(isolate); | 8096 HandleScope scope(isolate); |
| 8076 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); | 8097 RUNTIME_ASSERT(args.length() == 1 || args.length() == 2); |
| 8077 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 8098 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 8078 | 8099 |
| 8079 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); | 8100 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); |
| 8080 function->MarkForLazyRecompilation(); | 8101 function->MarkForLazyRecompilation(); |
| 8081 | 8102 |
| 8082 Code* unoptimized = function->shared()->code(); | 8103 Code* unoptimized = function->shared()->code(); |
| 8083 if (args.length() == 2 && | 8104 if (args.length() == 2 && |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8237 function->PrintName(); | 8258 function->PrintName(); |
| 8238 PrintF("]\n"); | 8259 PrintF("]\n"); |
| 8239 } | 8260 } |
| 8240 InterruptStub interrupt_stub; | 8261 InterruptStub interrupt_stub; |
| 8241 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate); | 8262 Handle<Code> interrupt_code = interrupt_stub.GetCode(isolate); |
| 8242 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement(); | 8263 Handle<Code> replacement_code = isolate->builtins()->OnStackReplacement(); |
| 8243 Deoptimizer::RevertInterruptCode(*unoptimized, | 8264 Deoptimizer::RevertInterruptCode(*unoptimized, |
| 8244 *interrupt_code, | 8265 *interrupt_code, |
| 8245 *replacement_code); | 8266 *replacement_code); |
| 8246 | 8267 |
| 8247 // Allow OSR only at nesting level zero again. | |
| 8248 unoptimized->set_allow_osr_at_loop_nesting_level(0); | |
| 8249 | |
| 8250 // If the optimization attempt succeeded, return the AST id tagged as a | 8268 // If the optimization attempt succeeded, return the AST id tagged as a |
| 8251 // smi. This tells the builtin that we need to translate the unoptimized | 8269 // smi. This tells the builtin that we need to translate the unoptimized |
| 8252 // frame to an optimized one. | 8270 // frame to an optimized one. |
| 8253 if (succeeded) { | 8271 if (succeeded) { |
| 8254 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); | 8272 ASSERT(function->code()->kind() == Code::OPTIMIZED_FUNCTION); |
| 8255 return Smi::FromInt(ast_id.ToInt()); | 8273 return Smi::FromInt(ast_id.ToInt()); |
| 8256 } else { | 8274 } else { |
| 8257 if (function->IsMarkedForLazyRecompilation()) { | 8275 if (function->IsMarkedForLazyRecompilation()) { |
| 8258 function->ReplaceCode(function->shared()->code()); | 8276 function->ReplaceCode(function->shared()->code()); |
| 8259 } | 8277 } |
| (...skipping 5214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13474 } else { | 13492 } else { |
| 13475 // Non-smi length argument produces a dictionary | 13493 // Non-smi length argument produces a dictionary |
| 13476 can_use_type_feedback = false; | 13494 can_use_type_feedback = false; |
| 13477 } | 13495 } |
| 13478 } | 13496 } |
| 13479 | 13497 |
| 13480 JSArray* array; | 13498 JSArray* array; |
| 13481 MaybeObject* maybe_array; | 13499 MaybeObject* maybe_array; |
| 13482 if (!type_info.is_null() && | 13500 if (!type_info.is_null() && |
| 13483 *type_info != isolate->heap()->undefined_value() && | 13501 *type_info != isolate->heap()->undefined_value() && |
| 13484 JSGlobalPropertyCell::cast(*type_info)->value()->IsSmi() && | 13502 Cell::cast(*type_info)->value()->IsSmi() && |
| 13485 can_use_type_feedback) { | 13503 can_use_type_feedback) { |
| 13486 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(*type_info); | 13504 Cell* cell = Cell::cast(*type_info); |
| 13487 Smi* smi = Smi::cast(cell->value()); | 13505 Smi* smi = Smi::cast(cell->value()); |
| 13488 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); | 13506 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); |
| 13489 if (holey && !IsFastHoleyElementsKind(to_kind)) { | 13507 if (holey && !IsFastHoleyElementsKind(to_kind)) { |
| 13490 to_kind = GetHoleyElementsKind(to_kind); | 13508 to_kind = GetHoleyElementsKind(to_kind); |
| 13491 // Update the allocation site info to reflect the advice alteration. | 13509 // Update the allocation site info to reflect the advice alteration. |
| 13492 cell->set_value(Smi::FromInt(to_kind)); | 13510 cell->set_value(Smi::FromInt(to_kind)); |
| 13493 } | 13511 } |
| 13494 | 13512 |
| 13495 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( | 13513 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( |
| 13496 *constructor, type_info); | 13514 *constructor, type_info); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13635 // Handle last resort GC and make sure to allow future allocations | 13653 // Handle last resort GC and make sure to allow future allocations |
| 13636 // to grow the heap without causing GCs (if possible). | 13654 // to grow the heap without causing GCs (if possible). |
| 13637 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13655 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13638 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13656 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13639 "Runtime::PerformGC"); | 13657 "Runtime::PerformGC"); |
| 13640 } | 13658 } |
| 13641 } | 13659 } |
| 13642 | 13660 |
| 13643 | 13661 |
| 13644 } } // namespace v8::internal | 13662 } } // namespace v8::internal |
| OLD | NEW |