| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 0, NULL, &caught_exception); | 1413 0, NULL, &caught_exception); |
| 1414 } | 1414 } |
| 1415 | 1415 |
| 1416 | 1416 |
| 1417 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); | 1417 Mutex* Debugger::debugger_access_ = OS::CreateMutex(); |
| 1418 Handle<Object> Debugger::event_listener_ = Handle<Object>(); | 1418 Handle<Object> Debugger::event_listener_ = Handle<Object>(); |
| 1419 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); | 1419 Handle<Object> Debugger::event_listener_data_ = Handle<Object>(); |
| 1420 bool Debugger::compiling_natives_ = false; | 1420 bool Debugger::compiling_natives_ = false; |
| 1421 bool Debugger::is_loading_debugger_ = false; | 1421 bool Debugger::is_loading_debugger_ = false; |
| 1422 bool Debugger::never_unload_debugger_ = false; | 1422 bool Debugger::never_unload_debugger_ = false; |
| 1423 DebugMessageThread* Debugger::message_thread_ = NULL; | |
| 1424 v8::Debug::MessageHandler Debugger::message_handler_ = NULL; | 1423 v8::Debug::MessageHandler Debugger::message_handler_ = NULL; |
| 1425 bool Debugger::message_handler_cleared_ = false; | 1424 bool Debugger::message_handler_cleared_ = false; |
| 1426 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; | 1425 v8::Debug::HostDispatchHandler Debugger::host_dispatch_handler_ = NULL; |
| 1427 int Debugger::host_dispatch_micros_ = 100 * 1000; | 1426 int Debugger::host_dispatch_micros_ = 100 * 1000; |
| 1428 DebuggerAgent* Debugger::agent_ = NULL; | 1427 DebuggerAgent* Debugger::agent_ = NULL; |
| 1429 LockingMessageQueue Debugger::command_queue_(kQueueInitialSize); | 1428 LockingCommandMessageQueue Debugger::command_queue_(kQueueInitialSize); |
| 1430 LockingMessageQueue Debugger::message_queue_(kQueueInitialSize); | |
| 1431 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); | 1429 Semaphore* Debugger::command_received_ = OS::CreateSemaphore(0); |
| 1432 Semaphore* Debugger::message_received_ = OS::CreateSemaphore(0); | |
| 1433 | 1430 |
| 1434 | 1431 |
| 1435 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, | 1432 Handle<Object> Debugger::MakeJSObject(Vector<const char> constructor_name, |
| 1436 int argc, Object*** argv, | 1433 int argc, Object*** argv, |
| 1437 bool* caught_exception) { | 1434 bool* caught_exception) { |
| 1438 ASSERT(Top::context() == *Debug::debug_context()); | 1435 ASSERT(Top::context() == *Debug::debug_context()); |
| 1439 | 1436 |
| 1440 // Create the execution state object. | 1437 // Create the execution state object. |
| 1441 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); | 1438 Handle<String> constructor_str = Factory::LookupSymbol(constructor_name); |
| 1442 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); | 1439 Handle<Object> constructor(Top::global()->GetProperty(*constructor_str)); |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1811 v8::Local<v8::Object> cmd_processor = | 1808 v8::Local<v8::Object> cmd_processor = |
| 1812 v8::Object::Cast(*fun->Call(api_exec_state, 0, NULL)); | 1809 v8::Object::Cast(*fun->Call(api_exec_state, 0, NULL)); |
| 1813 if (try_catch.HasCaught()) { | 1810 if (try_catch.HasCaught()) { |
| 1814 PrintLn(try_catch.Exception()); | 1811 PrintLn(try_catch.Exception()); |
| 1815 return; | 1812 return; |
| 1816 } | 1813 } |
| 1817 | 1814 |
| 1818 // Notify the debugger that a debug event has occurred unless auto continue is | 1815 // Notify the debugger that a debug event has occurred unless auto continue is |
| 1819 // active in which case no event is send. | 1816 // active in which case no event is send. |
| 1820 if (!auto_continue) { | 1817 if (!auto_continue) { |
| 1821 bool success = SendEventMessage(event_data); | 1818 bool success = InvokeMessageHandlerWithEvent(event_data); |
| 1822 if (!success) { | 1819 if (!success) { |
| 1823 // If failed to notify debugger just continue running. | 1820 // If failed to notify debugger just continue running. |
| 1824 return; | 1821 return; |
| 1825 } | 1822 } |
| 1826 } | 1823 } |
| 1827 | 1824 |
| 1828 // Process requests from the debugger. | 1825 // Process requests from the debugger. |
| 1829 while (true) { | 1826 while (true) { |
| 1830 // Wait for new command in the queue. | 1827 // Wait for new command in the queue. |
| 1831 if (Debugger::host_dispatch_handler_) { | 1828 if (Debugger::host_dispatch_handler_) { |
| 1832 // In case there is a host dispatch - do periodic dispatches. | 1829 // In case there is a host dispatch - do periodic dispatches. |
| 1833 if (!command_received_->Wait(host_dispatch_micros_)) { | 1830 if (!command_received_->Wait(host_dispatch_micros_)) { |
| 1834 // Timout expired, do the dispatch. | 1831 // Timout expired, do the dispatch. |
| 1835 Debugger::host_dispatch_handler_(); | 1832 Debugger::host_dispatch_handler_(); |
| 1836 continue; | 1833 continue; |
| 1837 } | 1834 } |
| 1838 } else { | 1835 } else { |
| 1839 // In case there is no host dispatch - just wait. | 1836 // In case there is no host dispatch - just wait. |
| 1840 command_received_->Wait(); | 1837 command_received_->Wait(); |
| 1841 } | 1838 } |
| 1842 | 1839 |
| 1843 // The debug command interrupt flag might have been set when the command was | 1840 // The debug command interrupt flag might have been set when the command was |
| 1844 // added. | 1841 // added. |
| 1845 StackGuard::Continue(DEBUGCOMMAND); | 1842 StackGuard::Continue(DEBUGCOMMAND); |
| 1846 | 1843 |
| 1847 // Get the command from the queue. | 1844 // Get the command from the queue. |
| 1848 Message command = command_queue_.Get(); | 1845 CommandMessage command = command_queue_.Get(); |
| 1849 Logger::DebugTag("Got request from command queue, in interactive loop."); | 1846 Logger::DebugTag("Got request from command queue, in interactive loop."); |
| 1850 if (!Debugger::IsDebuggerActive()) { | 1847 if (!Debugger::IsDebuggerActive()) { |
| 1851 // Delete command text and user data. | 1848 // Delete command text and user data. |
| 1852 command.Dispose(); | 1849 command.Dispose(); |
| 1853 return; | 1850 return; |
| 1854 } | 1851 } |
| 1855 | 1852 |
| 1856 // Invoke JavaScript to process the debug request. | 1853 // Invoke JavaScript to process the debug request. |
| 1857 v8::Local<v8::String> fun_name; | 1854 v8::Local<v8::String> fun_name; |
| 1858 v8::Local<v8::Function> fun; | 1855 v8::Local<v8::Function> fun; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1893 v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); | 1890 v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv); |
| 1894 if (!try_catch.HasCaught()) { | 1891 if (!try_catch.HasCaught()) { |
| 1895 running = running_val->ToBoolean()->Value(); | 1892 running = running_val->ToBoolean()->Value(); |
| 1896 } | 1893 } |
| 1897 } else { | 1894 } else { |
| 1898 // In case of failure the result text is the exception text. | 1895 // In case of failure the result text is the exception text. |
| 1899 response = try_catch.Exception()->ToString(); | 1896 response = try_catch.Exception()->ToString(); |
| 1900 } | 1897 } |
| 1901 | 1898 |
| 1902 // Return the result. | 1899 // Return the result. |
| 1903 SendMessage(Message::NewOutput(response, command.client_data())); | 1900 InvokeMessageHandler(response, command.client_data()); |
| 1904 | 1901 |
| 1905 // Return from debug event processing if either the VM is put into the | 1902 // Return from debug event processing if either the VM is put into the |
| 1906 // runnning state (through a continue command) or auto continue is active | 1903 // runnning state (through a continue command) or auto continue is active |
| 1907 // and there are no more commands queued. | 1904 // and there are no more commands queued. |
| 1908 if (running || (auto_continue && !HasCommands())) { | 1905 if (running || (auto_continue && !HasCommands())) { |
| 1909 return; | 1906 return; |
| 1910 } | 1907 } |
| 1911 } | 1908 } |
| 1912 } | 1909 } |
| 1913 | 1910 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1939 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data)); | 1936 event_listener_data_ = Handle<Object>::cast(GlobalHandles::Create(*data)); |
| 1940 } | 1937 } |
| 1941 | 1938 |
| 1942 // Unload the debugger if event listener cleared. | 1939 // Unload the debugger if event listener cleared. |
| 1943 if (callback->IsUndefined()) { | 1940 if (callback->IsUndefined()) { |
| 1944 UnloadDebugger(); | 1941 UnloadDebugger(); |
| 1945 } | 1942 } |
| 1946 } | 1943 } |
| 1947 | 1944 |
| 1948 | 1945 |
| 1949 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler, | 1946 void Debugger::SetMessageHandler(v8::Debug::MessageHandler handler) { |
| 1950 bool message_handler_thread) { | |
| 1951 ScopedLock with(debugger_access_); | 1947 ScopedLock with(debugger_access_); |
| 1952 | 1948 |
| 1953 message_handler_ = handler; | 1949 message_handler_ = handler; |
| 1954 if (handler != NULL) { | 1950 if (handler == NULL) { |
| 1955 if (!message_thread_ && message_handler_thread) { | |
| 1956 message_thread_ = new DebugMessageThread(); | |
| 1957 message_thread_->Start(); | |
| 1958 } | |
| 1959 } else { | |
| 1960 // Indicate that the message handler was recently cleared. | 1951 // Indicate that the message handler was recently cleared. |
| 1961 message_handler_cleared_ = true; | 1952 message_handler_cleared_ = true; |
| 1962 | 1953 |
| 1963 // Send an empty command to the debugger if in a break to make JavaScript | 1954 // Send an empty command to the debugger if in a break to make JavaScript |
| 1964 // run again if the debugger is closed. | 1955 // run again if the debugger is closed. |
| 1965 if (Debug::InDebugger()) { | 1956 if (Debug::InDebugger()) { |
| 1966 ProcessCommand(Vector<const uint16_t>::empty()); | 1957 ProcessCommand(Vector<const uint16_t>::empty()); |
| 1967 } | 1958 } |
| 1968 } | 1959 } |
| 1969 } | 1960 } |
| 1970 | 1961 |
| 1971 | 1962 |
| 1972 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, | 1963 void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, |
| 1973 int period) { | 1964 int period) { |
| 1974 host_dispatch_handler_ = handler; | 1965 host_dispatch_handler_ = handler; |
| 1975 host_dispatch_micros_ = period * 1000; | 1966 host_dispatch_micros_ = period * 1000; |
| 1976 } | 1967 } |
| 1977 | 1968 |
| 1978 | 1969 |
| 1979 // Calls the registered debug message handler. This callback is part of the | 1970 // Calls the registered debug message handler. This callback is part of the |
| 1980 // public API. Messages are kept internally as Vector<uint16_t> strings, which | 1971 // public API. Messages are kept internally as Vector<uint16_t> strings, which |
| 1981 // are allocated in various places and deallocated by the calling function | 1972 // are allocated in various places and deallocated by the calling function |
| 1982 // sometime after this call. | 1973 // sometime after this call. |
| 1983 void Debugger::InvokeMessageHandler(Message message) { | 1974 void Debugger::InvokeMessageHandler(v8::Handle<v8::String> output, |
| 1975 v8::Debug::ClientData* data) { |
| 1984 ScopedLock with(debugger_access_); | 1976 ScopedLock with(debugger_access_); |
| 1985 | 1977 |
| 1986 if (message_handler_ != NULL) { | 1978 if (message_handler_ != NULL) { |
| 1987 message_handler_(message.text().start(), | 1979 Vector<uint16_t> text = Vector<uint16_t>::New(output->Length()); |
| 1988 message.text().length(), | 1980 output->Write(text.start(), 0, output->Length()); |
| 1989 message.client_data()); | 1981 |
| 1982 message_handler_(text.start(), |
| 1983 text.length(), |
| 1984 data); |
| 1985 |
| 1986 text.Dispose(); |
| 1990 } | 1987 } |
| 1991 message.Dispose(); | 1988 delete data; |
| 1992 } | 1989 } |
| 1993 | 1990 |
| 1994 | 1991 |
| 1995 void Debugger::SendMessage(Message message) { | 1992 bool Debugger::InvokeMessageHandlerWithEvent(Handle<Object> event_data) { |
| 1996 if (message_thread_ == NULL) { | |
| 1997 // If there is no message thread just invoke the message handler from the | |
| 1998 // V8 thread. | |
| 1999 InvokeMessageHandler(message); | |
| 2000 } else { | |
| 2001 // Put the message coming from V8 on the queue. The text and user data will | |
| 2002 // be destroyed by the message thread. | |
| 2003 Logger::DebugTag("Put message on event message_queue."); | |
| 2004 message_queue_.Put(message); | |
| 2005 message_received_->Signal(); | |
| 2006 } | |
| 2007 } | |
| 2008 | |
| 2009 | |
| 2010 bool Debugger::SendEventMessage(Handle<Object> event_data) { | |
| 2011 v8::HandleScope scope; | 1993 v8::HandleScope scope; |
| 2012 // Call toJSONProtocol on the debug event object. | 1994 // Call toJSONProtocol on the debug event object. |
| 2013 v8::Local<v8::Object> api_event_data = | 1995 v8::Local<v8::Object> api_event_data = |
| 2014 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)); | 1996 v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)); |
| 2015 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol"); | 1997 v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol"); |
| 2016 v8::Local<v8::Function> fun = | 1998 v8::Local<v8::Function> fun = |
| 2017 v8::Function::Cast(*api_event_data->Get(fun_name)); | 1999 v8::Function::Cast(*api_event_data->Get(fun_name)); |
| 2018 v8::TryCatch try_catch; | 2000 v8::TryCatch try_catch; |
| 2019 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL); | 2001 v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL); |
| 2020 v8::Local<v8::String> json_event_string; | 2002 v8::Local<v8::String> json_event_string; |
| 2021 if (!try_catch.HasCaught()) { | 2003 if (!try_catch.HasCaught()) { |
| 2022 if (!json_event->IsUndefined()) { | 2004 if (!json_event->IsUndefined()) { |
| 2023 json_event_string = json_event->ToString(); | 2005 json_event_string = json_event->ToString(); |
| 2024 if (FLAG_trace_debug_json) { | 2006 if (FLAG_trace_debug_json) { |
| 2025 PrintLn(json_event_string); | 2007 PrintLn(json_event_string); |
| 2026 } | 2008 } |
| 2027 SendMessage(Message::NewOutput( | 2009 InvokeMessageHandler(json_event_string, |
| 2028 json_event_string, | 2010 NULL /* no user data since there was no request */); |
| 2029 NULL /* no user data since there was no request */)); | |
| 2030 } else { | 2011 } else { |
| 2031 SendMessage(Message::NewEmptyMessage()); | 2012 InvokeMessageHandler(v8::String::Empty(), NULL); |
| 2032 } | 2013 } |
| 2033 } else { | 2014 } else { |
| 2034 PrintLn(try_catch.Exception()); | 2015 PrintLn(try_catch.Exception()); |
| 2035 return false; | 2016 return false; |
| 2036 } | 2017 } |
| 2037 return true; | 2018 return true; |
| 2038 } | 2019 } |
| 2039 | 2020 |
| 2040 | 2021 |
| 2041 // Puts a command coming from the public API on the queue. Creates | 2022 // Puts a command coming from the public API on the queue. Creates |
| 2042 // a copy of the command string managed by the debugger. Up to this | 2023 // a copy of the command string managed by the debugger. Up to this |
| 2043 // point, the command data was managed by the API client. Called | 2024 // point, the command data was managed by the API client. Called |
| 2044 // by the API client thread. This is where the API client hands off | 2025 // by the API client thread. |
| 2045 // processing of the command to the DebugMessageThread thread. | |
| 2046 // The new copy of the command is destroyed in HandleCommand(). | |
| 2047 void Debugger::ProcessCommand(Vector<const uint16_t> command, | 2026 void Debugger::ProcessCommand(Vector<const uint16_t> command, |
| 2048 v8::Debug::ClientData* client_data) { | 2027 v8::Debug::ClientData* client_data) { |
| 2049 // Need to cast away const. | 2028 // Need to cast away const. |
| 2050 Message message = Message::NewCommand( | 2029 CommandMessage message = CommandMessage::New( |
| 2051 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), | 2030 Vector<uint16_t>(const_cast<uint16_t*>(command.start()), |
| 2052 command.length()), | 2031 command.length()), |
| 2053 client_data); | 2032 client_data); |
| 2054 Logger::DebugTag("Put command on command_queue."); | 2033 Logger::DebugTag("Put command on command_queue."); |
| 2055 command_queue_.Put(message); | 2034 command_queue_.Put(message); |
| 2056 command_received_->Signal(); | 2035 command_received_->Signal(); |
| 2057 | 2036 |
| 2058 // Set the debug command break flag to have the command processed. | 2037 // Set the debug command break flag to have the command processed. |
| 2059 if (!Debug::InDebugger()) { | 2038 if (!Debug::InDebugger()) { |
| 2060 StackGuard::DebugCommand(); | 2039 StackGuard::DebugCommand(); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2115 void Debugger::StopAgent() { | 2094 void Debugger::StopAgent() { |
| 2116 if (agent_ != NULL) { | 2095 if (agent_ != NULL) { |
| 2117 agent_->Shutdown(); | 2096 agent_->Shutdown(); |
| 2118 agent_->Join(); | 2097 agent_->Join(); |
| 2119 delete agent_; | 2098 delete agent_; |
| 2120 agent_ = NULL; | 2099 agent_ = NULL; |
| 2121 } | 2100 } |
| 2122 } | 2101 } |
| 2123 | 2102 |
| 2124 | 2103 |
| 2125 void Debugger::TearDown() { | 2104 CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), |
| 2126 if (message_thread_ != NULL) { | 2105 client_data_(NULL) { |
| 2127 message_thread_->Stop(); | |
| 2128 delete message_thread_; | |
| 2129 message_thread_ = NULL; | |
| 2130 } | |
| 2131 } | 2106 } |
| 2132 | 2107 |
| 2133 | 2108 |
| 2134 void DebugMessageThread::Run() { | 2109 CommandMessage::CommandMessage(const Vector<uint16_t>& text, |
| 2135 // Sends debug events to an installed debugger message callback. | 2110 v8::Debug::ClientData* data) |
| 2136 while (keep_running_) { | |
| 2137 // Wait and Get are paired so that semaphore count equals queue length. | |
| 2138 Debugger::message_received_->Wait(); | |
| 2139 Logger::DebugTag("Get message from event message_queue."); | |
| 2140 Message message = Debugger::message_queue_.Get(); | |
| 2141 if (message.text().length() > 0) { | |
| 2142 Debugger::InvokeMessageHandler(message); | |
| 2143 } else { | |
| 2144 message.Dispose(); | |
| 2145 } | |
| 2146 } | |
| 2147 } | |
| 2148 | |
| 2149 | |
| 2150 void DebugMessageThread::Stop() { | |
| 2151 keep_running_ = false; | |
| 2152 Debugger::SendMessage(Message::NewEmptyMessage()); | |
| 2153 Join(); | |
| 2154 } | |
| 2155 | |
| 2156 | |
| 2157 Message::Message() : text_(Vector<uint16_t>::empty()), | |
| 2158 client_data_(NULL) { | |
| 2159 } | |
| 2160 | |
| 2161 | |
| 2162 Message::Message(const Vector<uint16_t>& text, | |
| 2163 v8::Debug::ClientData* data) | |
| 2164 : text_(text), | 2111 : text_(text), |
| 2165 client_data_(data) { | 2112 client_data_(data) { |
| 2166 } | 2113 } |
| 2167 | 2114 |
| 2168 | 2115 |
| 2169 Message::~Message() { | 2116 CommandMessage::~CommandMessage() { |
| 2170 } | 2117 } |
| 2171 | 2118 |
| 2172 | 2119 |
| 2173 void Message::Dispose() { | 2120 void CommandMessage::Dispose() { |
| 2174 text_.Dispose(); | 2121 text_.Dispose(); |
| 2175 delete client_data_; | 2122 delete client_data_; |
| 2176 client_data_ = NULL; | 2123 client_data_ = NULL; |
| 2177 } | 2124 } |
| 2178 | 2125 |
| 2179 | 2126 |
| 2180 Message Message::NewCommand(const Vector<uint16_t>& command, | 2127 CommandMessage CommandMessage::New(const Vector<uint16_t>& command, |
| 2181 v8::Debug::ClientData* data) { | 2128 v8::Debug::ClientData* data) { |
| 2182 return Message(command.Clone(), data); | 2129 return CommandMessage(command.Clone(), data); |
| 2183 } | 2130 } |
| 2184 | 2131 |
| 2185 | 2132 |
| 2186 Message Message::NewOutput(v8::Handle<v8::String> output, | 2133 CommandMessageQueue::CommandMessageQueue(int size) : start_(0), end_(0), |
| 2187 v8::Debug::ClientData* data) { | 2134 size_(size) { |
| 2188 Vector<uint16_t> text; | 2135 messages_ = NewArray<CommandMessage>(size); |
| 2189 if (!output.IsEmpty()) { | |
| 2190 // Do not include trailing '\0'. | |
| 2191 text = Vector<uint16_t>::New(output->Length()); | |
| 2192 output->Write(text.start(), 0, output->Length()); | |
| 2193 } | |
| 2194 return Message(text, data); | |
| 2195 } | 2136 } |
| 2196 | 2137 |
| 2197 | 2138 |
| 2198 Message Message::NewEmptyMessage() { | 2139 CommandMessageQueue::~CommandMessageQueue() { |
| 2199 return Message(); | |
| 2200 } | |
| 2201 | |
| 2202 | |
| 2203 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) { | |
| 2204 messages_ = NewArray<Message>(size); | |
| 2205 } | |
| 2206 | |
| 2207 | |
| 2208 MessageQueue::~MessageQueue() { | |
| 2209 while (!IsEmpty()) { | 2140 while (!IsEmpty()) { |
| 2210 Message m = Get(); | 2141 CommandMessage m = Get(); |
| 2211 m.Dispose(); | 2142 m.Dispose(); |
| 2212 } | 2143 } |
| 2213 DeleteArray(messages_); | 2144 DeleteArray(messages_); |
| 2214 } | 2145 } |
| 2215 | 2146 |
| 2216 | 2147 |
| 2217 Message MessageQueue::Get() { | 2148 CommandMessage CommandMessageQueue::Get() { |
| 2218 ASSERT(!IsEmpty()); | 2149 ASSERT(!IsEmpty()); |
| 2219 int result = start_; | 2150 int result = start_; |
| 2220 start_ = (start_ + 1) % size_; | 2151 start_ = (start_ + 1) % size_; |
| 2221 return messages_[result]; | 2152 return messages_[result]; |
| 2222 } | 2153 } |
| 2223 | 2154 |
| 2224 | 2155 |
| 2225 void MessageQueue::Put(const Message& message) { | 2156 void CommandMessageQueue::Put(const CommandMessage& message) { |
| 2226 if ((end_ + 1) % size_ == start_) { | 2157 if ((end_ + 1) % size_ == start_) { |
| 2227 Expand(); | 2158 Expand(); |
| 2228 } | 2159 } |
| 2229 messages_[end_] = message; | 2160 messages_[end_] = message; |
| 2230 end_ = (end_ + 1) % size_; | 2161 end_ = (end_ + 1) % size_; |
| 2231 } | 2162 } |
| 2232 | 2163 |
| 2233 | 2164 |
| 2234 void MessageQueue::Expand() { | 2165 void CommandMessageQueue::Expand() { |
| 2235 MessageQueue new_queue(size_ * 2); | 2166 CommandMessageQueue new_queue(size_ * 2); |
| 2236 while (!IsEmpty()) { | 2167 while (!IsEmpty()) { |
| 2237 new_queue.Put(Get()); | 2168 new_queue.Put(Get()); |
| 2238 } | 2169 } |
| 2239 Message* array_to_free = messages_; | 2170 CommandMessage* array_to_free = messages_; |
| 2240 *this = new_queue; | 2171 *this = new_queue; |
| 2241 new_queue.messages_ = array_to_free; | 2172 new_queue.messages_ = array_to_free; |
| 2242 // Make the new_queue empty so that it doesn't call Dispose on any messages. | 2173 // Make the new_queue empty so that it doesn't call Dispose on any messages. |
| 2243 new_queue.start_ = new_queue.end_; | 2174 new_queue.start_ = new_queue.end_; |
| 2244 // Automatic destructor called on new_queue, freeing array_to_free. | 2175 // Automatic destructor called on new_queue, freeing array_to_free. |
| 2245 } | 2176 } |
| 2246 | 2177 |
| 2247 | 2178 |
| 2248 LockingMessageQueue::LockingMessageQueue(int size) : queue_(size) { | 2179 LockingCommandMessageQueue::LockingCommandMessageQueue(int size) |
| 2180 : queue_(size) { |
| 2249 lock_ = OS::CreateMutex(); | 2181 lock_ = OS::CreateMutex(); |
| 2250 } | 2182 } |
| 2251 | 2183 |
| 2252 | 2184 |
| 2253 LockingMessageQueue::~LockingMessageQueue() { | 2185 LockingCommandMessageQueue::~LockingCommandMessageQueue() { |
| 2254 delete lock_; | 2186 delete lock_; |
| 2255 } | 2187 } |
| 2256 | 2188 |
| 2257 | 2189 |
| 2258 bool LockingMessageQueue::IsEmpty() const { | 2190 bool LockingCommandMessageQueue::IsEmpty() const { |
| 2259 ScopedLock sl(lock_); | 2191 ScopedLock sl(lock_); |
| 2260 return queue_.IsEmpty(); | 2192 return queue_.IsEmpty(); |
| 2261 } | 2193 } |
| 2262 | 2194 |
| 2263 | 2195 |
| 2264 Message LockingMessageQueue::Get() { | 2196 CommandMessage LockingCommandMessageQueue::Get() { |
| 2265 ScopedLock sl(lock_); | 2197 ScopedLock sl(lock_); |
| 2266 Message result = queue_.Get(); | 2198 CommandMessage result = queue_.Get(); |
| 2267 Logger::DebugEvent("Get", result.text()); | 2199 Logger::DebugEvent("Get", result.text()); |
| 2268 return result; | 2200 return result; |
| 2269 } | 2201 } |
| 2270 | 2202 |
| 2271 | 2203 |
| 2272 void LockingMessageQueue::Put(const Message& message) { | 2204 void LockingCommandMessageQueue::Put(const CommandMessage& message) { |
| 2273 ScopedLock sl(lock_); | 2205 ScopedLock sl(lock_); |
| 2274 queue_.Put(message); | 2206 queue_.Put(message); |
| 2275 Logger::DebugEvent("Put", message.text()); | 2207 Logger::DebugEvent("Put", message.text()); |
| 2276 } | 2208 } |
| 2277 | 2209 |
| 2278 | 2210 |
| 2279 void LockingMessageQueue::Clear() { | 2211 void LockingCommandMessageQueue::Clear() { |
| 2280 ScopedLock sl(lock_); | 2212 ScopedLock sl(lock_); |
| 2281 queue_.Clear(); | 2213 queue_.Clear(); |
| 2282 } | 2214 } |
| 2283 | 2215 |
| 2284 #endif // ENABLE_DEBUGGER_SUPPORT | 2216 #endif // ENABLE_DEBUGGER_SUPPORT |
| 2285 | 2217 |
| 2286 } } // namespace v8::internal | 2218 } } // namespace v8::internal |
| OLD | NEW |